以HMAC密钥形式发放密钥令牌

功能如下

1:记录用户的登录的IP地址、时间

2:实现密码错误次数超限后锁定,并提示何时解锁

CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`(
`reqjson` JSON,
`srvjson` JSON
)
RETURNS json
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT 'JSON用户登录'
BEGIN
#SELECT `uc_session_login`('{"email":"xxscn@qq.com","pwdmd5":"md5加密后的密码"}','{"ipaddress":"用户登录的IP地址"}')json
DECLARE retjson JSON DEFAULT'{"errno":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 _beforedel 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),'{}');#IFNULL(@srvjson,'{}')#已由会话变量改为函数的参数
DECLARE secretkey2 VARCHAR(32)DEFAULT IFNULL(srvjson->>'$.secretkey2','');#二级密钥
DECLARE useripaddress VARCHAR(39)DEFAULT srvjson->>'$.ipaddress';#用户IP地址
DECLARE req_email VARCHAR(50)DEFAULT reqjson->>'$.email';
DECLARE req_pwdmd5 CHAR(32)DEFAULT reqjson->>'$.pwdmd5';
#与字段无关的输出
DECLARE json JSON DEFAULT'{}';
#首先判断IP地址是否已被禁止尝试密码
DELETE FROM uc_session_ipaddress WHERE beforedel<CURRENT_TIMESTAMP();#删除较早的IP
SET _failedlogins=0;
SELECT failedlogins,beforedel INTO _failedlogins,_beforedel FROM uc_session_ipaddress WHERE ipaddress=useripaddress;
IF _failedlogins>=failedlogins_max THEN
SET retjson=JSON_SET(retjson,'$.errno',-11);
SET retjson=JSON_SET(retjson,'$.message',CONCAT('由于密码错误次数过多,已被锁定。解锁时间:',_beforedel));
RETURN retjson;
END IF;
SELECT uid,username,`password`,salt INTO _uid,_username,_password,_salt FROM uc_members WHERE email=req_email;
IF ISNULL(_uid) THEN RETURN '{"error":-1,"message":"您输入的E-Mail尚未注册"}';END IF;
IF MD5(CONCAT(req_pwdmd5,_salt))<>_password THEN
INSERT INTO uc_session_log(uid,ipaddress,errno,error)VALUES(_uid,useripaddress,-2,'登录密码错误');
SET @curfailed=_failedlogins+1;
IF _failedlogins=0 THEN
#第一次密码错误
INSERT INTO uc_session_ipaddress(ipaddress,failedlogins,beforedel)VALUES(useripaddress,1,TIMESTAMPADD(SECOND,failedlogins_timeout,CURRENT_TIMESTAMP()));
ELSE
UPDATE uc_session_ipaddress SET failedlogins=@curfailed,beforedel=TIMESTAMPADD(SECOND,failedlogins_unlocktime,CURRENT_TIMESTAMP()) WHERE ipaddress=useripaddress;
END IF;
IF @curfailed>=failedlogins_max THEN
SET retjson=JSON_SET(retjson,'$.errno',-3);
SET retjson=JSON_SET(retjson,'$.message',CONCAT('由于密码错误次数已达',failedlogins_max,'次,现已被锁定',failedlogins_unlocktime,'秒'));
RETURN retjson;
END IF;
SET retjson=JSON_SET(retjson,'$.errno',-2);
SET retjson=JSON_SET(retjson,'$.message',CONCAT('您已输错',@curfailed,'次密码,如再错',failedlogins_max-@curfailed,'次将被锁定',failedlogins_unlocktime,'秒'));
RETURN retjson;
END IF;
#登录校验已通过,开始取得secretkey并出hmac
SELECT id,secretkey INTO _keyid,_secretkey FROM uc_session_key WHERE started<CURRENT_TIMESTAMP() AND expired>CURRENT_TIMESTAMP() ORDER BY expired DESC LIMIT 1;
IF ISNULL(_keyid) OR ISNULL(_secretkey) THEN RETURN '{"error":-3,"message":"secretkey获取失败"}';END IF;
SET json=JSON_SET(json,'$.logintime',UNIX_TIMESTAMP(CURRENT_TIMESTAMP(6)));
SET json=JSON_SET(json,'$.loginip',useripaddress);
SET json=JSON_SET(json,'$.uid',_uid);
SET json=JSON_SET(json,'$.email',req_email);
SET json=JSON_SET(json,'$.username',_username);
SET json=JSON_SET(json,'$.password',_password);
SET json=JSON_SET(json,'$.salt',_salt);
DELETE FROM uc_session_ipaddress WHERE ipaddress=useripaddress;#删除较早的IP
INSERT INTO uc_session_log(uid,ipaddress,errno,error)VALUES(_uid,useripaddress,0,'登录成功');
SET retjson=JSON_SET(retjson,'$.userjson',CAST(json AS CHAR));
SET retjson=JSON_SET(retjson,'$.keyid',_keyid);
SET retjson=JSON_SET(retjson,'$.hmacsha1',uc_session_hmacsha1(CONCAT(_secretkey,secretkey2),retjson->>'$.userjson'));
SET retjson=JSON_SET(retjson,'$.errno',0);
SET retjson=JSON_SET(retjson,'$.message','登录成功');
RETURN retjson;
END

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

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

    利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版) CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`( `reqjson` JS ...

  2. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  3. Struts2整合Hibernate3实现用户登录功能

    所用技术:struts2 ,hibernate,jsp,mysql 本DEMO仅仅实现用户登录功能,采用MVC思想,自己也觉得相对是比较简单,比较容易理解数据流向的一个例子,通过整合这个过程,能够清晰 ...

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

    使用JDBC.spring框架.servlet实现一个简单的用户登录功能. 一.mySql数据库 SET FOREIGN_KEY_CHECKS=0; -- ---------------------- ...

  5. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(五)——实现注册功能

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  6. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

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

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  8. VuePress 中增加用户登录功能

    在 VuePress 中增加用户登录 VuePress 是 Vuejs 官方提供的一个快速建设文档站点的工具,在简单配置好功能后,需要做的事情就剩下写好一个个 Markdown 文档. 因为 VueP ...

  9. 实现Web上的用户登录功能

    关于如何实现web上的自动登录功能 文章来源http://coolshell.cn/articles/5353.html Web上的用户登录功能应该是最基本的功能了,可是在我看过一些站点的用户登录功能 ...

随机推荐

  1. Servlet中的过滤器Filter

    链web.xml中元素执行的顺序listener->filter->struts拦截器->servlet. 1.过滤器的概念 Java中的Filter 并不是一个标准的Servlet ...

  2. Vue(一)

    一.es6语法:let和const es6新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. 上面代码在代码块之中,分别用let和var声明了两 ...

  3. excel中如何把文本转换为数字

     今天被一个小问题难住了,本人用自己开发的成绩分析软件统计学校成绩,数据由excel导入,给我的数据全部是文本型,其实也不难,主要是我的软件是早期开发的,没有考虑这个问题,结果这个问题被美女老师解决了 ...

  4. LL(1),LR(0),SLR(1),LR(1),LALR(1)的 联系与区别

    一:LR(0),SLR(1),规范LR(1),LALR(1)的关系     首先LL(1)分析法是自上而下的分析法.LR(0),LR(1),SLR(1),LALR(1)是自下而上的分析法.       ...

  5. HTTP的缓存策略

    etag 与 if-match https://www.cnblogs.com/huangzhilong/p/4999207.html https://juejin.im/post/5c136bd16 ...

  6. python mysql and ORM

    http://www.cnblogs.com/alex3714/articles/5950372.html 9. ORM sqlachemy学习 http://www.cnblogs.com/alex ...

  7. 唤醒实验(java

    package sy;import java.util.Random; public class random { public static void main(String[] args) { / ...

  8. Opencv undefined reference to `cv::imread() Ubuntu编译

    Ubuntu下编译一个C++文件,C++源程序中使用了opencv,opencv的安装没有问题,但是在编译的过程中出现如下错误: undefined reference to `cv::imread( ...

  9. My SQL随记 001 常用名词/结构化语言

    DBMS (Database Management System) 字段/域(列名或者列头 如:姓名身高性别为字段) 姓名 身高 性别 小周周 157 女 记录(一行数据 如:小周周 157 女 ) ...

  10. wpf-x-指令元素

    1. x:Code 用于代码前置  可以吧 C#代码内嵌到前端里 2. x:XData 用于内嵌xml 文件