MYSQL登录函数(第3版本)
已经改进
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','test@firadio.com','pwdmd5',MD5('test')),JSON_OBJECT('ipaddress','1.1.1.1'))json
DECLARE retjson JSON DEFAULT JSON_OBJECT('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 _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 IFNULL(srvjson->>'$.ipaddress',uc_session_ipaddress_client());#用户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();
IF ISNULL(req_appid) THEN
RETURN JSON_SET(retjson,'$.errno',-101,'$.message','appid不能为空');
END IF;
IF ISNULL(req_email) THEN
RETURN JSON_SET(retjson,'$.errno',-102,'$.message','email不能为空');
END IF;
IF ISNULL(req_pwdmd5) THEN
RETURN JSON_SET(retjson,'$.errno',-103,'$.message','pwdmd5不能为空');
END IF;
IF LENGTH(req_pwdmd5)<>32 THEN
RETURN JSON_SET(retjson,'$.errno',-104,'$.message','pwdmd5需要提供32个字符');
END IF;
#首先判断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 keyid,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,'$.keyid',_keyid);
#SET retjson=JSON_SET(retjson,'$.userjson',CAST(userjson AS CHAR));
#SET retjson=JSON_SET(retjson,'$.hmacsha1',uc_session_hmacsha1(CONCAT(_secretkey,secretkey2),retjson->>'$.userjson'));
SET retjson=JSON_SET(retjson,'$.sessdata',JSON_OBJECT('keyid',_keyid,'userjson',TO_BASE64(AES_ENCRYPT(userjson,CONCAT(_secretkey,secretkey2)))));
RETURN JSON_SET(retjson,'$.errno',0,'$.message','登录成功');
END
MYSQL登录函数(第3版本)的更多相关文章
- 利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版)
利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版) CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`( `reqjson` JS ...
- mysql常用函数参考
mysql常用函数参考 对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的最左面字符的ASCII代码值.如果str是空字符串,返回0.如果str是NULL, ...
- Mysql的函数使用方法
今天有点临时需求要计算一张表的结果,不想写代码,想到了mysql的自定义函数.碰到了很多问题,为了方便一下使用,在此记录一下. 需求:一张表中,有比分,需要查询出比赛id和比赛结果. 分析: ...
- MySQL聚合函数、控制流程函数(含navicat软件的介绍)
MySQL聚合函数.控制流程函数(含navicat软件的介绍) 一.navicat的引入:(第三方可视化的客户端,方便MySQL数据库的管理和维护) NavicatTM是一套快速.可靠并价格相宜的数据 ...
- MySQL登录汇总
--MySQL登录汇总 --------------------2014/5/17 1. ERROR 1045错误ERROR 1045 (28000): Access denied for user ...
- [转载]MySQL UUID() 函数
目录 目录 一 引子 二 MySQL UUID() 函数 三 复制中的 UUID()四 UUID_SHORT() 函数 3.1 实验环境介绍 3.2 搭建复制环境 3.3 基于 STATEMENT 模 ...
- MySQL 数学函数
MySQL 数学函数 所有的数学函数在发生错误的情况下,均返回 NULL. -元减.改变参数的符号 mysql> SELECT - 2; -> -2 注意,如果这个操作符被用于一个 BIG ...
- MySQL单行函数
1.CONCAT(str1,str2,...) 返回来自于参数连结的字符串.如果任何参数是NULL,返回NULL.可以有超过2个的参数.一个数字参数被变换为等价的字符串形式. select CONC ...
- Mysql下Limit注入方法(此方法仅适用于5.0.0<mysql<5.6.6的版本)
SQL语句类似下面这样:(此方法仅适用于5.0.0<mysql<5.6.6的版本) SELECT field FROM table WHERE id > 0 ORDER BY id ...
随机推荐
- Python_文件处理
1.Python 文件处理 打开文件---->读取内容---->获得内容 读取文件方式: r 只读文件 w 只写模式 a 追加模式 r+b 读写模式 w+b 写读模式 a+b ...
- 简单几步,教你学会PHP,新手必看!
学习php的方法,学东西,永远不要妄想有速成这一说,告诉你了一个方式,但是缺少努力这一环节,那也是白搭.掌握好的学习方法非常必要,看看这篇如何学习PHP培训的方法,在此提醒一下大家,PHP不像别的科目 ...
- python-django-01
1.Python工具 - pip 1.作用 Python的软件包管理器,有一些python包被集成到了pip中.只要被集成到pip中的包,都允许通过pip直接安装 2.安装 pip sudo apt ...
- swagger2常用注解
常用注解: @Api()用于类: 表示标识这个类是swagger的资源 @ApiOperation()用于方法: 表示一个http请求的操作 @ApiParam()用于方法,参数,字段说明: 表示对参 ...
- pymysql操作mysql的脚本示例
#!/usr/bin/env python#-*- coding:UTF-8 -*- from multiprocessing import Process , Queuefrom queue imp ...
- 学习笔记 Optional
今天学习到的一种新的防止空指针的方法下面是我自己写的一个例子:节省空间,bean的get set 省略... /** * 类目 * @author 唐 * @date 2018/5/6 17:45 * ...
- 田螺便利店—filezilla实现Linux和windows通信(二)
filezilla,FileZilla是一个免费开源的FTP软件,分为客户端版本和服务器版本,具备所有的FTP软件功能.可控性.有条理的界面和管理多站点的简化方式使得Filezilla客户端版成为一个 ...
- Spring+Mybatis+SpringMVC+Maven+MySql搭建实例(转)
http://blog.csdn.net/evankaka/article/details/48785513?spm=5176.100239.blogcont28591.10.9Fdj9R
- oracle数据库连接缓慢
今天连接数据库时非常的慢,大概将近1分钟,才能连上,感觉不对,登录数据库所在的服务器,进行检查,常规的内存.硬盘.CPU全都正常,然后想要进入oracle用户时报错了:su: cannot set u ...
- NABCD(团队项目)
N (Need 需求) 随着时代的进步和手机迅速发展,各种软件充斥这我们的生活,在学校里,我们总为一些各种各样的群所困扰,我们需要一件工具整合信息,让我们的生活更加便利. A (Approach 做法 ...