我一直在尝试在postgreSQL 9.4中创建一个基本的用户身份验证系统,但是一直在崩溃。我的用户表如下所示:
-- Users table
CREATE TABLE users (
user_id SERIAL NOT NULL PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
email TEXT NOT NULL,
password TEXT NOT NULL,
failed_login_attempts INT NOT NULL DEFAULT 0
CONSTRAINT positive_login_attempts CHECK (failed_login_attempts >= 0),
last_failed_login_attempt TIMESTAMP NULL,
UNIQUE(email),
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL,
deleted_at TIMESTAMP NULL
);
这些功能正常:
-- check to see if a user exists
CREATE OR REPLACE FUNCTION user_exists (auth_email VARCHAR(254))
RETURNS SETOF users AS $$
SELECT *
FROM users
WHERE email = auth_email
$$ LANGUAGE SQL;
-- authenticates a user against the system
CREATE OR REPLACE FUNCTION authenticate_user (auth_email VARCHAR(254), auth_password VARCHAR(72))
RETURNS SETOF users AS $$
SELECT *
FROM users
WHERE email = auth_email
AND password = crypt(auth_password, password))
$$ LANGUAGE SQL;
然而,当我尝试将它们结合起来时,我会趴在脸上。在半伪代码中,我想做的是:
-- login function
CREATE OR REPLACE FUNCTION user_login (auth_email VARCHAR(254), auth_password VARCHAR(72)) RETURNS SETOF users AS $$
IF EXISTS (SELECT COUNT(*) FROM user_exists(auth_email))
IF EXISTS (SELECT COUNT(*) FROM authenticate_user (auth_email, auth_password))
-- set the failed_login_attempts value to 0
-- set the last failed login attempt as NULL
-- return the user details
ELSE
-- increment the failed_login_attempts value
-- set the last failed login attempt as the current time
-- return nothing
END IF;
ELSE
-- return nothing
END IF;
$$ LANGUAGE SQL;
这可能吗?我完全走错了路线吗?
登录尝试失败的目的'将它设置为逐渐加长冷却期 - 例如失败尝试:
答案 0 :(得分:1)
是否需要使用SQL
语言编写函数?
如果您接受PLPGSQL
,则会有PLPGSQL
程序的解决方案。
CREATE OR REPLACE FUNCTION user_login (auth_email VARCHAR(254), auth_password VARCHAR(72))
RETURNS SETOF users AS
$$
DECLARE
found_user users;
BEGIN
SELECT u.*
FROM users u
WHERE u.email=auth_email
INTO found_user;
-- Check password here using your algorithm
IF found_user.password = auth_password THEN
RETURN NEXT found_user;
RETURN;
END IF;
UPDATE users SET
failed_login_attempts = failed_login_attempts + 1
, last_failed_login_attempt = now()
WHERE user_id = found_user.user_id;
END;
$$
LANGUAGE plpgsql;