首页> 中国专利> 一种基于JWT的自动续签认证方法

一种基于JWT的自动续签认证方法

摘要

本发明公开了一种基于JWT的自动续签认证方法,利用数据库添加、修改和查找唯一有效token的方法来验证JWT,并达到给JWT自动续签的目的;只有在需要添加JWT以及JWT超时和即将超时的时候签发新的token,并同步更新数据库和客户端的token,保证针对每个用户只存储一份最新的JWT;认证过程中,在传统单次验证token签名的流程上增加了与数据库token签名对比的二次验证,过滤掉未过期的失效JWT,有效解决了JWT无法自动续签的问题。本发明的方法可有效解决传统JWT续签方案服务器压力大、内存占用率高、刷新令牌过期和不能过滤未过期失效JWT的问题。

著录项

  • 公开/公告号CN112260838A

    专利类型发明专利

  • 公开/公告日2021-01-22

    原文格式PDF

  • 申请/专利权人 四川长虹电器股份有限公司;

    申请/专利号CN202011103322.0

  • 发明设计人 鲁享琳;

    申请日2020-10-15

  • 分类号H04L9/32(20060101);H04L29/06(20060101);

  • 代理机构51213 四川省成都市天策商标专利事务所;

  • 代理人郭会

  • 地址 621000 四川省绵阳市高新区绵兴东路35号

  • 入库时间 2023-06-19 09:38:30

说明书

技术领域

本发明涉及JWT认证技术领域,特别涉及一种基于JWT的自动续签认证方法。

背景技术

JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。服务器不保存任何用户信息,即JWT是无状态的。一旦签发一个JWT,在到期之前就会始终有效,无法中途废弃。要改变JWT的有效时间,就要签发新的JWT。但是如果存在已经发布且还没过期的JWT,由于旧的JWT还没过期,拿着这个旧的JWT依旧可以登录,那登录后服务端从JWT中拿到的信息就是过时的。所以,JWT不支持自动续签。

目前,针对上述问题现有技术中大致有以下三类处理方式:

1.每次请求都返回一个新的JWT给客户端。每次收到请求都要重新运算出新的JWT,加大了服务器的处理压力。

2.在redis中单独为每个JWT设置了过期时间,每次访问时刷新JWT的过期时间,若JWT不存在于redis中则认为过期。这会占用大量内存空间,大大提高了redis缓存的故障概率。

3.同时签发两个token:access_token和refresh_token。refresh_token的有效时间比access_token长,专门用于access_token续签的时候刷新token。但是refresh_token过期后,就无法续签了。

因此,在JWT标准下,token都是无状态的,所以上述三种方式都不能过滤未过期的失效JWT。

发明内容

本发明的目的是克服上述背景技术中不足,提供一种基于JWT的自动续签认证方法,利用数据库添加、修改和查找唯一有效token的方法来验证JWT,并达到给JWT自动续签的目的;只有在需要添加JWT以及JWT超时和即将超时的时候签发新的token,并同步更新数据库和客户端的token,保证针对每个用户只存储一份最新的JWT;认证过程中,在传统单次验证token签名的流程上增加了与数据库token签名对比的二次验证,过滤掉未过期的失效JWT,有效解决了JWT无法自动续签的问题。

为了达到上述的技术效果,本发明采取以下技术方案:

一种基于JWT的自动续签认证方法,包括以下步骤:

A.建立token的数据库存储表用于存储token信息;包括:主键、用户id、token值、认证状态;其中,用户id用于存储用户的唯一标识,token值用于存储最新有效的JWT,认证状态用于记录该用户是否正在进行身份认证流程;

B.生成新的JWT;所述JWT由三部分组成:用于存放签名采用的加密方式的头部header、存放有效信息的载荷payload、签名signature;

C.截取token中的payload载荷部分,获取用户id和过期时间;

D.根据获取的过期时间,在JWT过期或即将过期时生成新token并传给客户端;

E.对每一次认证流程进行防重复认证检测,保证每个用户同时只能触发一个认证;

F.设置cookie为HttpOnly,实现XSS攻击功能;XSS(Cross site script,跨站脚本攻击),通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序;这些恶意网页程序通常是JavaScript;攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容;设置cookie为HttpOnly,意味着只能由服务端保存以及通过自动回传的cookie取得token,以便防御XSS攻击;

G.截取客户端提交的token,验证token在传输过程中是否被篡改以及客户端提交的是否是最新的token;

H.在用户登录和操作认证时,新增缺少的JWT,为超时和即将超时的token续签。

进一步地,JWT的组成部分中,header及payload均由Base64加密,signature是通过将header及payload的密文用句号连接起来,通过header中声明的加密方式进行加盐secret组合加密生成的,将用户id加密可避免直接暴露用户标识。

进一步地,所述步骤B中生成新的JWT时是把过期时间和加密后的用户id作为playload成员生成新的JWT。

进一步地,所述步骤C中具体是通过截取token中的payload载荷部分,用Base64解密,获取过期时间和加密后的用户id,并解密用户id。

进一步地,所述步骤D中具体是依据步骤C获取的过期时间和用户id,将过期时间和当前时间对比,判断是否超时或即将超时;如果超时或即将超时,则依照步骤B生成包含新过期时间和加密用户id的新token,并将此token更新进数据库中用户id对应的token字段,再将新token传给客户端。

进一步地,所述步骤G具体是将客户端提交的token中header部分用Base64解密,获取签名加密方式,然后采取header密文+"."+payload密文的格式通过secret秘钥进行header指定的加密运算生成签名1;

然后截取客户端提交的token中的signature签名部分,存为签名2;再验证签名1和签名2是否一致,若不一致,则说明token在传输过程中被篡改,则认证失败;若一致则可继续进一步认证步骤。

进一步地,所述进一步认证步骤即获数据库中用户id对应的token,截取此token的签名,存为签名3,判定签名2和签名3是否一致,若不一致,则说明客户端提交的不是最新的token,则认证失败;若一致则token签名认证成功。

进一步地,所述步骤H具体包括:

若用户首次登录时,token表没有此用户的信息,验证完用户名和密码后,依照步骤B生成JWT,并在token表新增一条存储用户id和JWT的记录;

若用户非首次登录,验证完用户名和密码后,得到用户id,从而获取数据库中用户对应的token值;依照步骤D,如果超时或即将超时,则生成新的JWT,并同步更新给数据库和客户端;否则,继续沿用数据库存储的token值;

用户验证身份时,依据步骤C,获取用户id和过期时间,获取获数据库中用户id对应的token进行相应的验证;且通过步骤G的token签名验证后,依照步骤D,如果超时和即将超时,生成新的JWT,并同步更新给数据库和客户端;否则,继续沿用数据库存储的token值。

进一步地,所述token表的认证状态初始值是未认证,在进入认证流程时,变为进入认证;认证流程结束时,恢复为未认证。

进一步地,所述步骤E具体是在每一次发起的认证流程中均对认证状态进行检测,且只要检测到认证状态是进入认证时都要中止认证,从而保证每个用户同时只能触发一个认证,防止过度请求消耗服务器资源。

本发明与现有技术相比,具有以下的有益效果:

本发明的基于JWT的自动续签认证方法,采用在数据库添加、修改和查找唯一有效token的方法,解决JWT无法自动续签的问题,本发明的技术方案中只有在需要添加JWT以及JWT超时和即将超时的时候生成token,不用像背景技术中介绍的现有方式1每次请求都重新生成JWT;且由于利用了数据库存储,也不会和背景技术中介绍的现有方式2一样占用太多内存空间;续签时同步更新客户端和数据库存放的token,因此,不会像背景技术中介绍的现有方式3刷新token时,有refresh_token过期无法续签的问题;每个用户在数据库中只存储一份最新的JWT,结合与数据库token签名的二次对比验证,能弥补背景技术中介绍的三种方式不能过滤未过期失效JWT的缺点,即能在JWT超时和即将超时的时候自动续签JWT,并实现客户端和服务器的同步更新。有效解决传统JWT续签方案服务器压力大、内存占用率高、刷新令牌过期和不能过滤未过期失效JWT的问题。

附图说明

图1是本发明的方法中用户登录认证流程示意图。

图2是本发明的方法中用户操作认证流程示意图。

图3是本发明的一个实施例中token验证表结构示意图。

具体实施方式

下面结合本发明的实施例对本发明作进一步的阐述和说明。

实施例:

实施例一:

一种基于JWT的自动续签认证方法,如图1和图2所示,具体包括以下步骤:

步骤1,建立token的数据库存储表。关系模式为:主键、用户id、token值、认证状态,本实施例中建立的token验证表具体如图3所示,其中,用户id用来存储用户的唯一标识,token值用来存储最新有效的JWT,认证状态记录该用户是否正在进行身份认证流程。

步骤2,客户端提交用户名和密码,服务器对比存储的用户信息,验证通过后,获取用户标识user_id,通过user_id搜索token验证表里对应记录。若该条记录不存在,执行步骤3、步骤4;若该条记录存在,执行步骤5。

即本发明的方法中在用户登录和认证时会在数据库添加、修改和查找唯一有效的token值,从而过滤掉未过期的失效JWT。

步骤3,payload明文中加入user_id密文和过期时间,将加密好的JWT三部分header、payload、signature组合,形成新的token。例如:

S3.1.将JWT头部(header)明文{"typ":"JWT","alg":"HS256"},用Base64加密生成密文eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9。

S3.2.假设步骤2中获取的user_id为1,用aes加密,且秘钥为123,则生成密文U2FsdGVkX1+0xgFIiWTGGWv6aiRY5umOASz42+VxipE=。

S3.3.假设当前时间是2020-08-02 20:07:49,设置30min过期,即2020-08-0220:37:49过期,过期时间取值2020-08-02 20:37:49时间戳1596371869。

S3.4.由S3.2和S3.23获得包含user_id密文和过期时间的JWT载荷(payload)明文:

{"exp":"1596371869","user_code":"U2FsdGVkX1+0xgFIiWTGGWv6aiRY5umOASz42+VxipE="},其中exp是过期时间戳。

将payload用Base64加密生成密文:

eyJleHAiOiIxNTk2MzcxODY5IiwidXNlcl9jb2RlIjoiVTJGc2RHVmtYMSswe GdGSWlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==。

S3.5.将header和payload的Base64密文用”.”连接,得到eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxNTk2MzcxODY5IiwidXNlcl9jb2RlIjoiVTJGc2RHVmtYMSsweGdGS WlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==。

以456为秘钥对这个字符串做HS256加密,得到签名(signature)部分:807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad3c41019ee780c88d。

S3.6.将header、payload、signature三部分用”.”连接,得到JWT:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxNTk2MzcxODY5IiwidX Nlcl9jb2RlIjoiVTJGc2RHVmtYMSsweGdGSWlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==.807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad3c41019ee780c88d。

步骤4,在数据库中插入一条存储user_id、token且state值为0的记录{"user_id":1,"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxNT k2MzcxODY5IiwidXNlcl9jb2RlIjoiVTJGc2RHVmtYMSsweGdGSWlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==.807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad3c41019ee780c88d","state":0}。

步骤5,获取数据库中对应的token,将payload部分截取出来,用Base64解密payload,获取过期时间。若当前已超时或快超时,把新的过期时间和加密后的user_id作为playload成员生成新的JWT,更新数据库中user_id对应的token字段为新token。

即根据过期时间和当前时间判断是否超时和即将超时,如果超时和即将超时,则生成新的token,并同步更新服务器和客户端存储的token值,从而达到自动续签token值的效果。

例如,在数据库中搜到token:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxNTk2MzcxODY5Ii widXNlcl9jb2RlIjoiVTJGc2RHVmtYMSsweGdGSWlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==.807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14b ad3c41019ee780c88d。

截取payload部分:

eyJleHAiOiIxNTk2MzcxODY5IiwidXNlcl9jb2RlIjoiVTJGc2RHVmtYMSswe GdGSWlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==,

用Base64解密得到明文:

{"exp":"1596371869","user_code":"U2FsdGVkX1+0xgFIiWTGGWv6aiRY5umOASz42+VxipE="},其中exp是过期时间戳,即2020-08-02 20:37:49过期。

若到期前3分钟为即将超时,当前时间是2020-08-02 20:09:49,则未超时且未即将超时,数据库中的token可以直接使用。

若当前时间是2020-08-02 20:35:49,即即将超时;或者当前时间是2020-08-0220:40:49已经超时,则执行步骤3,生成新的JWT,更新数据库中user_id对应的token字段为新token。

步骤6,服务器设置cookie为HttpOnly,将步骤3或步骤4得到的最新的token传给客户端,客户端将此token存入cookie。

步骤7,用户做需要身份认证的操作时,客户端通过http的Authorization请求头发送token给服务器。

例如,发送步骤04中的token值,Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxNTk2MzcxODY5IiwidX Nlcl9jb2RlIjoiVTJGc2RHVmtYMSsweGdGSWlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==.807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad3c41019ee780c88d。

步骤8,服务器用secret秘钥对token的payload部分解密,获取过期时间和加密的user_id,解密user_id。

例如,服务器获取步骤04中的token值,截取payload部分:eyJleHAiOiIxNTk2MzcxODY5IiwidXNlcl9jb2RlIjoiVTJGc2RHVmtYMSsweGdGS WlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==。

用Base64解密得到明文:

{"exp":"1596371869","user_code":"U2FsdGVkX1+0xgFIiWTGGWv6aiRY5umOASz42+VxipE="}。由exp值得到到期时间戳为1596371869,即2020-08-0220:37:49;用秘钥123对user_code值用aes解密,得到user_id为1。

步骤9,查询步骤8获得的user_id对应的数据库记录是否存在。若不存在,说明该用户没有用账号登录,服务器通知前端验证失败,流程到此结束。若存在,继续执行步骤10。

步骤10,数据库中,如果user_id对应的state值是1,说明此用户有正在进行的验证动作,服务器通知客户端验证中,避免重复验证,流程到此结束。如果user_id对应的state值是0,说明此用户没有未完成的验证动作,继续步骤11。

步骤11,将数据库中user_id对应的state值置为1,标志此用户进入验证流程

步骤12,将客户端提交的token中header部分用Base64解密,获取签名加密方式。将客户端提交的token中header密文+"."+payload密文通过secret秘钥进行header指定的加密运算,生成签名1;截取客户端提交的token中的signature签名部分,存为签名2。

步骤13,如果签名1和签名2不一致,说明token在传输过程中存在被篡改的情况,服务器通知客户端验证失败,流程到此结束;如果签名1和签名2一致,说明token在传输过程中未被篡改,可以继续步骤14过程。

例如,步骤7提交的token中header密文是eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9。用Base64解密得到{"typ":"JWT","alg":"HS256"},即签名加密方式为HS256。

header密文+"."+payload密文为eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOiIxNTk2MzcxODY5IiwidXNlcl9jb2RlIjoiVTJGc2RHVmtYMSsweGdGS WlXVEdHV3Y2YWlSWTV1bU9BU3o0MitWeGlwRT0ifQ==,

用秘钥456对其进行HS256加密,得到:

807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad3c41019ee780c88d,记为签名1。

若截取步骤7提交的token中signature密文部分:807c3c910b1ab79b06625fc16edaafd8ba8ff84258b,记为签名2,签名1和签名2不一致,服务器通知客户端验证失败,流程到此结束。

若截取步骤7提交的token中signature密文部分:807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad3c41019ee780c88d,记为签名2,签名1和签名2一致,可以继续步骤14。

步骤14,获数据库中user_id对应的token,截取此token的签名,存为签名3。

步骤15,如果签名2签名3不一致,说明客户端提交的不是最新的token,服务器通知客户端验证失败,流程到此结束;如果签名2和签名3一致,说明客户端提交的是最新的token,可以继续步骤16。

例如,步骤12获得的签名2:807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad3c41019ee780c88d。

如果数据库中user_id对应的token签名部分为807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad,记为签名3,和签名2不一致,服务器通知客户端验证失败,流程到此结束。

如果数据库中user_id对应的token签名部分为807c3c910b1ab79b06625fc16edaafd8ba8ff84258b14bad3c41019ee780c88d,记为签名3,和签名2一致,执行步骤16。

步骤16,根据步骤7解密出的过期时间判断是否超时和即将超时。如果已经超时或即将超时,执行步骤18过程。如果没有超时和即将超时,执行步骤19。

步骤18,执行步骤3,生成新的JWT,将此token更新进数据库中user_id对应的token字段。

步骤19,将数据库中user_id对应的state值置为0,标志此用户进验证流程结束。服务器通知客户端验证通过。

综上,本发明的方法中,在用户登录和认证时在数据库添加、修改和查找唯一有效的token值,从而过滤掉未过期的失效JWT,且根据过期时间和当前时间判断是否超时和即将超时,如果超时和即将超时,生成新的token,并同步更新服务器和客户端存储的token值,从而达到自动续签token值的效果,同时,在传统对客户端提交的JWT一次验证的基础上,加入了与数据库存储token值的二次验证,保证客户端和服务器存储token的一致性,且在第二次验证数据库所存token值的时候,只对比签名部分,降低了服务器运算压力,同时,还给每个用户分配一个认证状态,默认是未认证。在进入认证流程时,变为进入认证;认证流程结束时,恢复未认证。每一次发起的认证流程,只要检测到认证状态是进入认证都要中止,从而保证每个用户同时只能触发一个认证,防止过度请求消耗服务器资源,且在JWT的payload载荷部分,加入用户id密文,既能帮助确认用户信息,又能避免直接暴露用户标识,对于用户非首次登陆且token未过期,则可以直接使用数据库的token,从而降低服务器运算压力。因此,本发明的方法能在JWT超时和即将超时的时候自动续签JWT,并实现客户端和服务器的同步更新,解决传统JWT续签方案服务器压力大、内存占用率高、刷新令牌过期和不能过滤未过期失效JWT的问题。

可以理解的是,以上实施方式仅仅是为了说明本发明的原理而采用的示例性实施方式,然而本发明并不局限于此。对于本领域内的普通技术人员而言,在不脱离本发明的精神和实质的情况下,可以做出各种变型和改进,这些变型和改进也视为本发明的保护范围。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号