利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版)

CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`(
    `reqjson` JSON,
    `srvjson` JSON
)
RETURNS json
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ‘UC的用户登录,返回JSON‘
BEGIN
    #调用例子
    #SELECT `uc_session_login`(JSON_OBJECT(‘appid‘,1,‘email‘,‘[email protected]‘,‘pwdmd5‘,MD5(‘test‘)),JSON_OBJECT(‘ipaddress‘,‘1.1.1.1‘))json
    DECLARE retjson JSON DEFAULT JSON_OBJECT(‘error‘,0);
    #密钥表
    DECLARE _keyid INT(10)UNSIGNED;
    DECLARE _secretkey CHAR(32);
    #登录表
    DECLARE _uid INT(10)UNSIGNED;
    DECLARE _username VARCHAR(50);
    DECLARE _password CHAR(32);
    DECLARE _salt CHAR(6);
    #地址记录表
    DECLARE _failedlogins INT(10)UNSIGNED;
    DECLARE _resetwhen TIMESTAMP;#计次重置时间
    #与字段无关的输入
    DECLARE failedlogins_max INT(10)UNSIGNED DEFAULT 3;#密码错误次数上限
    DECLARE failedlogins_timeout INT(10)UNSIGNED DEFAULT 20;#时间范围内清零计数
    DECLARE failedlogins_unlocktime INT(10)UNSIGNED DEFAULT 10;#密码错误次数超限后锁定时间
    #DECLARE srvjson JSON DEFAULT IFNULL(CAST(@srvjson AS CHAR),JSON_OBJECT());#已由会话变量改为函数的参数
    DECLARE secretkey2 VARCHAR(32)DEFAULT IFNULL(srvjson->>‘$.secretkey2‘,‘‘);#二级密钥
    DECLARE useripaddress VARCHAR(39)DEFAULT srvjson->>‘$.ipaddress‘;#用户IP地址
    DECLARE req_appid INT UNSIGNED DEFAULT reqjson->>‘$.appid‘;
    DECLARE req_email VARCHAR(50)DEFAULT reqjson->>‘$.email‘;
    DECLARE req_pwdmd5 CHAR(32)DEFAULT reqjson->>‘$.pwdmd5‘;
    #与字段无关的输出
    DECLARE userjson JSON DEFAULT JSON_OBJECT();
    #首先判断IP地址是否已被禁止尝试密码
    #DELETE FROM uc_session_ipaddress WHERE resetwhen<CURRENT_TIMESTAMP();#删除较早的IP
    UPDATE uc_session_ipaddress SET failedlogins=0 WHERE resetwhen<CURRENT_TIMESTAMP();#重置已超时的计数
    SET _failedlogins=0;
    SELECT failedlogins,resetwhen INTO _failedlogins,_resetwhen FROM uc_session_ipaddress WHERE ipaddress=useripaddress FOR UPDATE;
    IF _failedlogins>=failedlogins_max THEN
        RETURN JSON_SET(retjson,‘$.errno‘,-11,‘$.message‘,CONCAT(‘由于密码错误次数过多,已被锁定。解锁时间:‘,_resetwhen));
    END IF;
    SELECT uid,username,`password`,salt INTO _uid,_username,_password,_salt FROM uc_members WHERE email=req_email FOR UPDATE;
    IF ISNULL(_uid) THEN RETURN JSON_SET(retjson,‘$.errno‘,-1,‘$.message‘,‘您输入的E-Mail尚未注册‘);END IF;
    IF MD5(CONCAT(req_pwdmd5,_salt))<>_password THEN
        INSERT INTO uc_session_loginlog(appid,uid,ipaddress,errno,error)VALUES(req_appid,_uid,useripaddress,-2,‘登录密码错误‘);
        SET @curfailed=_failedlogins+1;#当前计数值
        SET @resetwhen_timeout=TIMESTAMPADD(SECOND,failedlogins_timeout,CURRENT_TIMESTAMP());#清零计数的时间
        IF ISNULL(_resetwhen) THEN#记录为空只能新增
            INSERT INTO uc_session_ipaddress SET ipaddress=useripaddress,failed=CURRENT_TIMESTAMP(),failedlogins=1,faileduid=_uid,resetwhen=@resetwhen_timeout ON DUPLICATE KEY UPDATE failed=VALUES(failed),failedlogins=VALUES(failedlogins),faileduid=VALUES(faileduid),resetwhen=VALUES(resetwhen);
        ELSEIF _failedlogins=0 THEN
            #记录第一次密码错误,并设置新的计数超时时间
            UPDATE uc_session_ipaddress SET failed=CURRENT_TIMESTAMP(),failedlogins=@curfailed,faileduid=_uid,resetwhen=@resetwhen_timeout WHERE ipaddress=useripaddress;
        ELSE
            UPDATE uc_session_ipaddress SET failed=CURRENT_TIMESTAMP(),failedlogins=@curfailed,faileduid=_uid,resetwhen=TIMESTAMPADD(SECOND,failedlogins_unlocktime,CURRENT_TIMESTAMP()) WHERE ipaddress=useripaddress;
        END IF;
        IF @curfailed>=failedlogins_max THEN
            RETURN JSON_SET(retjson,‘$.errno‘,-3,‘$.message‘,CONCAT(‘由于密码错误次数已达‘,failedlogins_max,‘次,现已被锁定‘,failedlogins_unlocktime,‘秒‘));
        END IF;
        RETURN JSON_SET(retjson,‘$.errno‘,-2,‘$.message‘,CONCAT(‘您已输错‘,@curfailed,‘次密码,如再错‘,failedlogins_max-@curfailed,‘次将被锁定‘,failedlogins_unlocktime,‘秒‘));
    END IF;
    #登录校验已通过
    #开始取得secretkey并出hmac
    SELECT id,secretkey INTO _keyid,_secretkey FROM uc_session_keycenter WHERE appid=req_appid AND expired>CURRENT_TIMESTAMP() LIMIT 1;
    IF ISNULL(_keyid) OR ISNULL(_secretkey) THEN RETURN JSON_SET(retjson,‘$.errno‘,-4,‘$.message‘,‘secretkey获取失败‘);END IF;
    SET userjson=JSON_SET(userjson,‘$.logintime‘,UNIX_TIMESTAMP(CURRENT_TIMESTAMP()),‘$.loginip‘,useripaddress);
    SET userjson=JSON_SET(userjson,‘$.uid‘,_uid,‘$.email‘,req_email,‘$.username‘,_username,‘$.password‘,_password,‘$.salt‘,_salt);
    IF ISNULL(_resetwhen) THEN#记录为空只能新增
        INSERT INTO uc_session_ipaddress SET ipaddress=useripaddress,failedlogins=0,succeed=CURRENT_TIMESTAMP(),succeeduid=_uid,succeedlogins=1 ON DUPLICATE KEY UPDATE failedlogins=VALUES(failedlogins),succeed=VALUES(succeed),succeeduid=VALUES(succeeduid),succeedlogins=succeedlogins+1;
    ELSE
        UPDATE uc_session_ipaddress SET failedlogins=0,succeed=CURRENT_TIMESTAMP(),succeeduid=_uid,succeedlogins=succeedlogins+1 WHERE ipaddress=useripaddress;
    END IF;
    INSERT INTO uc_session_loginlog(appid,uid,ipaddress,errno,error)VALUES(req_appid,_uid,useripaddress,0,‘登录成功‘);
    SET retjson=JSON_SET(retjson,‘$.userjson‘,CAST(userjson AS CHAR),‘$.keyid‘,_keyid);
    SET retjson=JSON_SET(retjson,‘$.hmacsha1‘,uc_session_hmacsha1(CONCAT(_secretkey,secretkey2),retjson->>‘$.userjson‘));
    RETURN JSON_SET(retjson,‘$.errno‘,0,‘$.message‘,‘登录成功‘);
END

原文地址:https://www.cnblogs.com/xiangxisheng/p/9886461.html

时间: 2024-11-06 20:57:38

利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版)的相关文章

Linux系统裁减之,制作一个极度精简的Linux-4-为精简的Linux 系统增加用户登录功能

第4章 为精简的Linux 系统增加用户登录功能 4.1下载mingetty和login程序源码 本文使用的CentOS 5.11的源代码都在官方源码网站http://vault.centos.org可以下载, 到http://vault.centos.org/5.11/os/Source/查找mingetty和login程序,如下图: ? ? mingetty和login程序分别属于mingetty-1.07-5.2.2和util-linux-2.13-0.59.el5_8软件包: [[ema

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(三)——使用Flask-Login库实现登录功能

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 本次示例的源码下载:点击下载 Flask-Login 库的中文文档:点击进入 Flask-Login 库的新版英文文档:点击进入 一.导入并初始化 Flask-Login 库 在项目根目录下的/demo/__init__.py 文件的头部,import 进 flask_login 库 from flask_login imp

JavaWeb学习记录(六)——用户登录功能

使用JDBC.spring框架.servlet实现一个简单的用户登录功能. 一.mySql数据库 SET FOREIGN_KEY_CHECKS=0; -- ------------------------------ Table structure for user-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` (  `id` int(11) NOT NULL AUTO_INCREMEN

[转]你会做Web上的用户登录功能吗?

转自:http://coolshell.cn/articles/5353.html Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能后,我觉得很有必要写一篇文章教大家怎么来做用户登录功能.下面的文章告诉大家这个功能可能并没有你所想像的那么简单,这是一个关系到用户安全的功能,希望大家能从下面的文章中能知道什么样的方法才是一个好的用户登录功能.以下内容,转载时请保持原文一致,并请注明作者和出处. 用户名和口令 首先,我们先来说说用户名和口令的事.这并不是本站第一次谈论这

如何设计安全的用户登录功能

用户登录功能是Web应用系统具备的最基本的功能,关系到用户数据和应用系统数据的安全,设计一个安全的用户登录功能,涉及到以下几个方面的内容. (一) 老生常谈——口令 1. 口令长度与复杂度限制 限制用户输入一些非常容易被破解的口令,比如qwert.asdfg.123456.password之类的,参考twitter和 facebook的设计,为这样的口令做一个黑名单,不允许使用黑名单中的口令.同时,还对用户口令的长度.复杂度进行检查,要求用户设置足够长度,且复 杂度符合安全策略的口令. 在口令安

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(四)——对 run.py 的调整

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(三)——使用Flask-Login库实现登录功能 为了方便以后的应用切换,所以需要对 run.py 里的代码进行调整下. 1.在/demo 目录下创建 app_start.py /demo/app_start.py # config=utf-8 from demo

实现Web上的用户登录功能

你会做Web上的用户登录功能吗? Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能后,我觉得很有必要写一篇文章教大家怎么来做用户登录功能.下面 的文章告诉大家这个功能可能并没有你所想像的那么简单,这是一个关系到用户安全的功能,希望大家能从下面的文章中能知道什么样的方法才是一个好的用户登录 功能 用户名和口令 首先,我们先来说说用户名和口令的事.这并不是本站第一次谈论这个事了.如何管理自己的口令让你知道怎么管理自己的口令,破解你的口令让你知道在现代这样速度的计算速度下

你会做Web上的用户登录功能吗?

Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能后,我觉得很有必要写一篇文章教大家怎么来做用户登录功能.下面的文章告诉大家这个功能可能并没有你所想像的那么简单,这是一个关系到用户安全的功能,希望大家能从下面的文章中能知道什么样的方法才是一个好的用户登录功能.以下内容,转载时请保持原文一致,并请注明作者和出处. 用户名和口令 首先,我们先来说说用户名和口令的事.这并不是本站第一次谈论这个事了.如何管理自己的口令让你知道怎么管理自己的口令,破解你的口令让你知道在现代这样

菜鸟级springmvc+spring+mybatis整合开发用户登录功能(上)

菜鸟级springmvc+spring+mybatis整合开发用户登录功能(上) 菜鸟级springmvc+spring+mybatis整合开发用户登录功能(下)