图片 3

依照Cookie的SSO登入深入分析和兑现,的解决方案

Posted by

Atitit.  单点登录sso 的解决方案 总结

一:理解单系统登录的原理及实现?

什么是SSO?

现在很多大的互联网公司都会有很多的应用,比如以下是淘宝网的截图:

图片 1

天猫 聚划算
头条等都是不同的应用,有的甚至采用完全不同的域名,但是所有在淘宝注册的用户都是使用的一套用户名和口令,如果在这些系统直接切换做不到登陆状态的同
步,体验是非常差的。再举个栗子,很多公司内部系统也有很多个,比如HR系统,财务系统,考勤系统等等,如果员工在一个系统登陆了,跳转到另外一个系统还
需要登陆,就会让人很不爽…

基于此,SSO(Single Sign On)应运而生。当然,我们来现实这个需求的方法有很多种,使用Cookie是其中比较简单的方式,主要需要解决的问题是:Cookie是不能跨域传递的,如何将一个域的Cookie通知给其它应用(不在同一个域)?

so,如果你对cookie机制不太熟悉,请先google,并大致了解为什么cookie会设计成不能跨域等相关问题。

 

web应用采用的 browser/server
架构的,http是无状态协议的,也就是说用户从A页面跳转到B页面会发起http请求,当服务器返回响应后,当用户A继续访问其他页面的时候,服务器端无法获知该状态,因此会使用cookie/session来记录用户状态的。

如何实现?

SSO有以下几种方式实现

1. 系统应用场景and SSO模式选型
2

session认证状态的基本原理:当客户端向服务器端请求时,会创建一个session标识存在客户端的cookie当中,每次请求的时候会将该标识随cookie一起发送到服务器端,服务器端会首先检查这个客户端的请求里面是否包含了一个session的标识,如果已经包含了,那么服务器端就会根据该session标识来判断用户的状态,否则的话,服务器端会创建一个新的session标识传给客户端的cookie当中,以后每次客户端请求的时候,会从cookie中获取该标识传递过去。

共享Cookie

当我们的子系统都在一个父级域名下时,我们可以将Cookie种在父域下,这样浏览器同域名下的Cookie则可以共享,这样可以通过Cookie加解密的算法获取用户SessionID,从而实现SSO。
但是,后面我们发现这种方式有几种弊端:
a. 所有同域名的系统都能获取SessionID,易被修改且不安全;
b. 跨域无法使用。

2. 系统应用的原则与要求
2

二:理解单点登录的原理?

ticket验证,我们目前采取的是这种方式

这种实现的SSO有以下几个步骤:
a. 用户访问某个子系统,发现如果未登录,则引导用户跳转到SSO登录页面;
b. 判断SSO是否已经登录;
c. 如果已经登录,直接跳转到回调地址,并返回认证ticket;
d.
如果未登录,用户正确输入用户名/密码,认证通过跳转到回调地址,并返回认证ticket;
e. 子系统获取ticket,调用SSO获取用户uid等信息,成功后让用户登录。

前面已经说了,如何通过Cookie来实现SSO,主要是如何解决跨域问题。首先来谈谈Set-Cookie中的domain属性。

2.1. 开发快速简单::绝大部分系统来说,开发快速简单为主
2

上面使用session/cookie
可以实现单个系统的登录,那如果是多个系统的话,怎么办?难道需要用户一个个去登录?
一个个去注销?我们需要做的是,无论系统有多少个,我们只需要登录一次就够了,其他的相关的系统都可以登录/注销一次即可。

Cookie domain

为了让Http协议在一定程度上保持上下文,server在响应的头部可以加入Set-Cookie来写入一些数据到客户端,Set-Cookie中的domain字段用来表示这个cookie所在的域。
栗子:
我们访问www.cookieexm.com,如果server在返回头部中加入了Set-Cookie,如果不指定domain,那么默认这个cookie的域就是www.cookieexm.com,也就是只有访问www.cookieexm.com时客户端才会把这个cookie返给服务端。
如果我们指定domain.cookieexm.com,那么客户端在访问以下域名:www.cookieexm.com www1.cookieexm.com a.cookieexm.com ***.cookieexm.com
时都能够把cookie返回。
所以,我们得出一条结论:客户端对cookie的domain的匹配是从结尾进行匹配的,有了这个基础,我们就可以实现我们的SSO登陆了。

cookie中需要注意的

  • 设置为http-only
  • 涉及登录凭证(如票据或者用户名)应该加密
  • cookie不能存放隐私数据

2.2. 支持token交换,这样有利于集成先有的系统模块无需大改动,仅仅需要改动登陆模块。。
2

单系统登录解决方案的核心是cookie,cookie会携带服务器端返回的sessionId,
在浏览器与服务器端维护会话状态。但是我们知道cookie是有限制的,cookie有域的概念,浏览器发送http请求时会自动匹配该本站点的cookie域。而不是所有的cookie。

具体方案

假设我们需要在如下子系统
**.a1.a2 **.b1.b2 **.c1.c2间实现单点登录,首先我们需要一个专门用于单点登陆的认证系统(sso.s1.s2)。假设目前系统处于未登录状态,访问www.a1.a2为例:

图片 2

 

分别看一下每个步骤作用:

  1. 请求www.a1.a2
  2. www.a1.a2收到请求,检查是否携带登录的cookie,目前没有登陆过,那么重定向到sso认证中心
  3. SSO提供登陆窗口,用户输入用户名 口令。SSO系统验证用户名和口令
  4. 这一步是关键,如果登录成功,首先把SSO系统的Cookie放到客户端;同时,将用户的认证信息传递通过重定向传递给业务方,注意,这个传递明显不能通过cookie来传递(不同域嘛),一般是通过加密的querystring。
  5. 业务方的验证系统收到sso认证信息,再进行认证
  6. 业务方认证通过之后,把认证结果的cookie写入到.a1.a2,至此,SSO认证完成
  7. 重定向到业务系统www.a1.a2,由前面的结论可知,此时所有以.a1.a2结尾的业务系统都可以使用这个认证之后的cookie
  8. response

说明:
业务认证系统不一定存在,有些不是太敏感的系统可以直接从SSO Authorization重定向到业务系统,并把SSO的认证信息带过去。

承接上文,此时,如果用户访问www.b1.b2应用,如下图所示:

图片 3

 

与访问www.a1.a2不同的是我们在重定向到SSO Authorization时已经不需要再去输入用户名,因为sso.s1.s2此时已经存有cookie,直接用cookie验证。
以上,就是一个简单的基于Cookie的登陆系统。

 

2.3. 支持用户名映射.当多个子系统username不同时候儿
2

那么既然这样,我们很容易想到的是,我们可以把所有子系统的域名都放在一个顶级域名下不就可以了?比如
“*.taobao.com”,然后将他们的cookie域设置为 “taobao.com”,
但是这种并不好:

其中几个问题需要重点解决

  • 如何高效存储大量临时性的信任数据
  • 如何防止信息传递过程被篡改
  • 如何让SSO系统信任登录系统和免登系统

对于第一个问题,一般可以采用类似与memcached的分布式缓存的方案,既能提供可扩展数据量的机制,也能提供高效访问

对于第二个问题,一般采取数字签名的方法,要么通过数字证书签名,要么通过像md5的方式,这就需要SSO系统返回免登URL的时候对需验证的参数进行
md5加密,并带上token一起返回,最后需免登的系统进行验证信任关系的时候,需把这个token传给SSO系统,SSO系统通过对token的验证
就可以辨别信息是否被改过

对于最后一个问题,可以通过白名单来处理,说简单点只有在白名单上的系统才能请求生产信任关系,同理只有在白名单上的系统才能被免登录。

 

转载地址:

3. 脱机验证sso (分散认证,类似护照的识别方式)
2

第一:因为所有系统的域名需要统一,比如淘宝和天猫的域名就不相同;
第二:应用群各个系统所使用的技术需要相同,比如tomcat服务器叫JESSIONID,
其他的服务器可能不叫这个标识。
第三:cookie的安全性不高的。

3.1. 适合场景:: 高性能场景,支持单方面改造
3

因此我们需要一种全新的方式来实现多系统应用群的登录,这就是单点登录。

3.2. 缺点::  需要对各个子系统的token格式较为了解。。
3

什么是单点登录?单点登录的全称是 Single Sign On ,
在多个系统中只要登录一次,便可以在其他所有系统中得到授权而无需再次登录。

4. 分散式联机认证+Token交换
3

SSO有一个独立的认证中心,认证中心它可以接受用户的用户名密码等安全信息,其他的地方不接受登录入口,只接受认证中心的间接授权,间接授权它是通过令牌实现的。授权令牌作为参数会发送到各个子系统,子系统拿到令牌,因此会得到了授权,因此就可以创建了局部的会话。局部会话和单系统登录的原理很类似的。

4.1. 原理::
3

下面我们来打个比方理解单点登录的基本原理:

4.2. 适合场景:: 绝大部分场景..需要双向改造
3

第一步:我想登录A系统,A系统发现用户未登录,因此我们需要他们跳转到SSO认证中心(且将自己请求的地址作为参数传递过去)。SSO认证中心发现未登录,会将用户引导到登录页面。

4.3. 主要的流程
3

第二步:用户输入用户名和密码提交申请登录,SSO认证中心会检测用户名和密码信息,如果用户名和密码正确的话,那么用户和SSO认证中心之间会创建一个局部会话,并且创建一个授权令牌。sso认证中心会带着该令牌跳转到A系统那个请求的地址去。

4.3.1. —A系统建立token检验API(   web系统通常是session,cookie等, )  , 就是把检验登录login.jsp那个代码复制过来,稍微修改一哈… 例如建立 loginValidApi.jsp
4

第三步:A系统会检测该令牌,如果有效的话,就会跳到用户输入的地址页面去,否则,还是返回登录页面,提示错误信息。

4.3.2. 访问B系统某个模块
4

第四步:用户访问系统B,系统B发现用户未登录,会跳转到SSO认证中心(将自己请求的地址作为参数传递过去),sso认证中心发现用户已经登录了,会跳转回系统B的那个地址去,并带上令牌,系统B拿到令牌,就会去sso认证中心去校验该令牌是否有效。
如果有效的话,说明认证成功了,就会跳转到系统B访问地址的页面上去。

4.3.3. B会检测是否在本系统登录,如登录,正常的访问…。。。。如未有登录,B系统在没修改的情形哈,会跳转到login.php..我们修改这个跳转,,先跳转到loginX.php(这个页面是需要我们建立的)
4

用户现在已经登录成功了,sso认证中心会与各个子系统建立会话,用户与sso认证中心建立的会话被称为全局会话,用户与各个
子系统建立的会话被称为局部会话,局部会话建立之后,用户访问子系统资源后就不会再通过sso认证中心了。

4.3.4. 在loginX.php中,把token转交给A验证(使用redirect转发 )…   跳转到 loginValidApi.jsp
4


4.3.5. –A的loginValidApi.jsp检测是否在本系统登录,如登录,把userA的信息返回B的loginX.php页面。。如没有登录,也是返回loginX.php(当然这种情况用户信息就为空了)。。
4

三:什么是JSON Web Token?

4.3.6. B系统loginX.php检测用户信息,如果没有用户信息,说明在A系统也没有登录。。
4

JSON Web Token
是一个开放标准协议,它定义了一种紧凑和自包含的方式,它用于各方之间作为JSON对象安全地传输信息。

4.3.7. 如果有其他的多个系统C,DE等,依次访问其api接口
4

它有如下优点:

4.3.8. 如果都没有登录,就转向login.php,进入普通登录。。。如有返回用户信息,说明已经在A系统登录了..  此时,如果A,B系统同一用户的username各不相同,需要做用户名映射 ,,userA>>userB …..。
5

1. 可以适用于分布式的单点登录场景。
2. 可以使用跨域认证解决方案。
3. jwt实现自动刷新token的方案。

4.3.9. 查询UserB信息,生成B系统的token  ( 这个代码通常可以从B系统的登录代码中copy过来稍微修改哈)..
5

JSON Web
Token,它定义了一种紧凑和自包含的方式,如何理解紧凑和自包含呢?

4.3.10. 跳转到B的那个模块,就会做为登录状态访问了.
5

紧凑:就是说这个数据量比较少,并且能通过url参数,http请求提交的数据以及http
header的方式来传递。
自包含:这个串可以包含很多信息,比如用户id,订单号id等,如果其他人拿到该信息,就可以拿到关键业务信息。

4.3.11. 访问A系统模块的流程可以参照这个,增加LoginX.jsp跟。loginValidApi.php就可以了。
5

3.1)JWT的基本原理,基本流程如下:

4.4. Token交换
5

  1. 客户端使用账号和密码请求登录接口。
  2. 登录成功后服务器使用签名密钥生成JWT,然后返回JWT给客户端。
  3. 客户端再次向服务端请求其他接口时会带上JWT。
  4. 服务器接收到JWT后验证签名的有效性,对客户端做出相应的响应。

4.5. 用户名映射
5

3.2)JWT与session的区别?

5. CAS开源单点登录SSO组件(统一的认证中心)
5

session是基于cookie来传输的,session信息是存储在服务器端中,客户端向服务器端发请求时,服务器端会返回一个jessionId给客户端中的cookie中,以后每次请求都会从cookie中的jessionid传递过去,服务器通过cookie中的sessionid获取到当前会话的用户,对于单系统来讲这是没有问题的,但是对于多个系统的话就涉及到session如何共享的问题了,并且随着认证用户增多的话,session会占用大量服务器内存。

5.1. Cas原理  ::所有应用系统共享一个身份认证系统。
5

JWT是存储在客户端的,服务器端不需要存储JWT,JWT含有用户id,服务器拿到jwt验证后就可以拿到用户信息了,jwt是无状态的,它不与任何机器绑定的,只要签名密钥足够的安全就能保证jwt的可靠性。

5.2. 适合场景:: 新的开发子系统
6

3.3)JWT中的token与session中的token安全性比较

5.3. 缺点::   要是在已有子系统引进,修改开发工作量大的(三方修改),,回归测试量大的..就算是使用了cas框架.
6

session 中安全性问题:

6. 参考 6

服务器端执行session机制的时候会生成session的口令,在Tomcat服务器中,默认会采用
jsessionid 这个值,但是在其他服务器上会有所不同,比如Connect默认会叫
connect_uid,
我们一般把一些敏感的信息放在cookie中是不可取的,但是将口令放在cookie中还是可以的,如果口令被篡改了的话,就丢失了映射关系,也无法修改服务器端存在的数据,并且session的有效期一般为20/30分钟,如果在该时间之内客户端和服务器端没有产生任何交互,服务器端会自动将session自动清空,因此session中想要维护用户一直登陆的状态的话,需要客户端每隔20分钟使用setInterval自动发一个请求给服务器端,这样的话,前后端就有交互,所以就可以一直保持登陆状态。否则的话,每次20分钟后,登陆状态就会失效,每隔20分钟用户需要重新登录,用户体验将会变得不好。session这样做的最主要的是为了安全性考虑,有效期的时间非常短,防止黑客攻击。

 

JWT方案中安全性问题

 

jwt是存储在客户端的,服务器端不需要存储jwt的,客户端每次发送请求时会携带该token,然后到服务器端会验证token是否正确,是否过期了,然后会通过解码出携带的用户的信息的,但是如果token在传输的过程中被攻击者截取了的话,那么对方就可以伪造请求,利用窃取到的token模拟正常请求,实现用户的正常操作,而服务器端完全不知道,因为JWT在服务器端是无状态的,且服务器端不存储jwt的。其实jwt解决的问题是认证和授权的问题,对于安全性的话,还是建议对外公布的接口使用https.

1. 系统应用场景and SSO模式选型

要是多个已经存在的系统,做sso, 做好使用”分散式联机认证模式”,开发量测试最少

已经存在的多系统,,需要高性能,使用”分散认证脱机验证sso “模式

新的开发的系统,可以使用cas 等的统一的认证中心  方式…

 

四:理解JWT的基本数据结构

2. 系统应用的原则与要求

基本的JWT的数据结构是如下这样的:

2.1. 开发快速简单::绝大部分系统来说,开发快速简单为主

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoia29uZ3poaSIsImlhdCI6MTU0Mzc1MzczNX0.h1XmQo017udxlFsH-8US9Lg8dJ0IDsSbRbjEN5Nq0l4

2.2. 支持token交换,这样有利于集成先有的系统模块无需大改动,仅仅需要改动登陆模块。。

如上它是由三部分组成的,中间使用 . 分割成三个部分,它是有 Header,
PayLoad,Signature组成的。
如:Header.Payload.Signature

2.3. 支持用户名映射.当多个子系统username不同时候儿

 

作者:: 老哇的爪子 Attilax 艾龙,  EMAIL:1466519819@qq.com

转载请注明来源: 

 

4.1 Header

3. 脱机验证sso (分散认证,类似护照的识别方式)

用一个现实中的例子做比较。 著名的旅游景点, 内部有许多独立的景点,例如“苏州 街”、“佛香阁”和“德和园”,都可以在各个景点门口单独买票。很多游客需要游玩所有德景点,这种买票方式很不方便,需要在每个景点门口排队买票,钱包拿 进拿出的,容易丢失,很不安全。于是绝大多数游客选择在大门口买一张通票(也叫套票),就可以玩遍所有的景点而不需要重新再买票。他们只需要在每个景点门 口出示一下刚才买的套票就能够被允许进入每个独立的景点。

Header部分是一个JSON对象,描述JWT的元数据,一般是如下的样子:

3.1. 适合场景:: 高性能场景,支持单方面改造

还有个优点是,可以单个子系统实现,无需俩边系统都改。。特别适合只能修改一方系统的情形…

{  "typ": "JWT",  "alg": "HS256"}

3.2. 缺点::  需要对各个子系统的token格式较为了解。。

如上json代码,alg属性表示签名的算法,默认是 HMAC SHA256 (缩写为:HS256);
typ属性表示这个令牌的类型为JWT. 最后将上面的JSON对象使用
Base64URL的算法转成字符串。
我们可以使用在线的base64编码转下(

4. 分散式联机认证+Token交换

图片 4

4.1. 原理::

例如银行验证身份证,,除了验证身份证本身的物理防伪。。更需要连接(身份验证机构的)远程身份验证接口来验证身份信息。

 

 

如上 alg 部分,默认加密的算法是 HMAC SHA256,
当然我们也可以选择下面的加密算法,加密算法有如下:

4.2. 适合场景:: 绝大部分场景..需要双向改造

图片 5

4.3. 主要的流程

例如::A系统(java系统) 互相集成 B系统(php论坛),,现今开始使用b的某一模块

 

4.2 Payload

4.3.1. —A系统建立token检验API(   web系统通常是session,cookie等, )  , 就是把检验登录login.jsp那个代码复制过来,稍微修改一哈… 例如建立 loginValidApi.jsp

Payload部分也是一个JSON对象,用来存放实际需要传递的数据,官方提供了7个字段,如下:

4.3.2. 访问B系统某个模块

图片 6

4.3.3. B会检测是否在本系统登录,如登录,正常的访问…。。。。如未有登录,B系统在没修改的情形哈,会跳转到login.php..我们修改这个跳转,,先跳转到loginX.php(这个页面是需要我们建立的)

iss: 签发人exp (expiration time): 过期时间sub : 主题aud : 受众nbf (Not Before): 生效时间iat (Issued At): 签发时间jti : 编号

4.3.4. 在loginX.php中,把token转交给A验证(使用redirect转发 )…   跳转到 loginValidApi.jsp

图片 7

4.3.5. –A的loginValidApi.jsp检测是否在本系统登录,如登录,把userA的信息返回B的loginX.php页面。。如没有登录,也是返回loginX.php(当然这种情况用户信息就为空了)。。

payload的中文含义是载荷,它可以理解为存放有效信息的地方。这些有效信息一般包含如下三个部分:

4.3.6. B系统loginX.php检测用户信息,如果没有用户信息,说明在A系统也没有登录。。

4.2.1)标准中注册的声明:(如上就是官方提供的7个字段)。

4.3.7. 如果有其他的多个系统C,DE等,依次访问其api接口

 

4.2.2)公共的声明:公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但是不建议添加敏感信息,
因为该部分在客户单可解密。

4.3.8. 如果都没有登录,就转向login.php,进入普通登录。。。如有返回用户信息,说明已经在A系统登录了..  此时,如果A,B系统同一用户的username各不相同,需要做用户名映射 ,,userA>>userB …..。

4.2.3)私有的声明:私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,该部分信息
可以理解为明文信息。

4.3.9. 查询UserB信息,生成B系统的token  ( 这个代码通常可以从B系统的登录代码中copy过来稍微修改哈)..

那么定义一个简单的 payload 可以如下结构:

4.3.10. 跳转到B的那个模块,就会做为登录状态访问了.

{  "sub": '123456',  "name": "kongzhi",  "admin": true}

4.3.11. 访问A系统模块的流程可以参照这个,增加LoginX.jsp跟。loginValidApi.php就可以了。

我们还是使用如上的base64编码,会编码成如下所示:

4.4. Token交换

图片 8

4.5. 用户名映射

 

 

4.3 Signature

5. CAS开源单点登录SSO组件(统一的认证中心)

Signature
是对前面两部分的签名,防止数据被篡改。签名是把Header和payload对应的json结构进行base64
编码之后得到的两个串用英文句点号拼接起来的,然后会根据header里面的alg指定的前面算法(默认是
HMAC SHA256)生成出来的。
如上header部分使用的是
HS256(即HMAC和SHA256),HMAC是用于生成摘要的,SHA256是用于对摘要进行数字签名的。因此使用HMACSHA256实现signature实现的算法如下:

5.1. Cas原理  ::所有应用系统共享一个身份认证系统。

们提供的CAS开源单点登录SSO组件,它部署节点主要有2个:SSO服务器(部署内容为一个web应用)、应用系统客户端(部署内容为cas客户端 casclient.jar包和相关配置文件)。因此我们根据SSO机制分析一下什么情况下会出现超时。多个应用系统进行SSO集成后,SSO单点登录过 程中,登录成功后,应用系统客户端(以下用浏览器客户端为例)的session会保存认证后的用户上下文,SSO服务器会生成一个用户凭证票据(TGT) 并缓存起来,浏览器客户端会保存TGC(浏览器cookie中存储的TGT),TGT是作为发放SSO访问服务的票据(ST)的一个凭证票据,发放ST票 据后才能正常访问

 

CAS开源单点登录SSO组件就提供了这个机制。我研究了CAS源码,基本明白了jsessionid的处理机制。大致原理如下:用户访问业务系 统,SSO客户端拦截,重定向到SSO服务器认证时,就将请求路径uri中写入”;jsessionid=具体的session值”,SSO服务器可以分 辨出这个标识值与其他客户端请求不同,进行认证处理,返回的响应给客户端cookie同时也设置了jsessionid的值,之所以在uri和 cookie中都设置了jsessionid,是为了双重保障能设置jsessionid值。最后单点登录成功后,返回业务系统访问地址也带有 jsessionid参数,这个在uri地址中看起来很别扭。

 

HMACSHA256(  base64UrlEncode + '.' +   base64UrlEncode,  secret)

5.2. 适合场景:: 新的开发子系统

如上是 Signature 签名算法,最后一个 secret
是加密的密钥的含义。因此通过如上的用法我们就可以拿到JWT了。

5.3. 缺点::   要是在已有子系统引进,修改开发工作量大的(三方修改),,回归测试量大的..就算是使用了cas框架.

 

4.4 JWT实践

6. 参考

SSO之CAS单点登录实例演示 _ micmiu – 软件开发+生活点滴.htm

SSO(单点登录)实施中遇到的几个问题 – yan_dk的专栏 – 博客频道 – CSDN.NET.htm

 

SSO单点登录解决方案[转载] – 走在架构师的大道上 Jack.Wang’s home – BlogJava.htm

( 离线检验 )单点登录SSO的实现原理 – 走向架构师之路 – 博客频道 – CSDN.NET.htm

图片 9

JWT的格式是由三个点分割的base64-URL字符串,可以在html或http环境中传递,我们可以简单的使用
图片 10

五:node中使用JWT的API

nodejs实现的jwt的github代码()

它主要有3个方法:

5.1 jwt.sign(payload, secretOrPrivateKey, [options, callback])

payload 参数必须是一个object、Buffer、或 string.
注意:exp
只有当payload是object字面量时才可以设置。如果payload不是buffer或string,它会被强制转换为使用的字符串JSON.stringify()。

secretOrPrivateKey
参数
是包含HMAC算法的密钥或RSA和ECDSA的PEM编码私钥的string或buffer。

options 参数有如下值:

图片 11

algorithm:加密算法(默认值:HS256)expiresIn:以秒表示或描述时间跨度zeit / ms的字符串。如60,"2 days","10h","7d",含义是:过期时间notBefore:以秒表示或描述时间跨度zeit / ms的字符串。如:60,"2days","10h","7d"audience:Audience,观众issuer:Issuer,发行者jwtid:JWT IDsubject:Subject,主题noTimestampheader

图片 12

该方法如果是异步方法,则会提供回调,如果是同步的话,则将会
JsonWebToken返回为字符串。
在expiresIn, notBefore, audience, subject,
issuer没有默认值时,可以直接在payload中使用 exp, nbf, aud, sub
和iss分别表示。

注意:如果在jwts中没有指定
noTimestamp的话,在jwts中会包含一个iat,它的含义是使用它来代替实际的时间戳来计算的。

下面我们在项目中使用node中jsonwebtoken来生成一个JWT的demo了,在index.js
代码如下:

图片 13

// 生成一个tokenconst jwt = require('jsonwebtoken');const secret = 'abcdef';let token = jwt.sign({  name: 'kongzhi'}, secret, (err, token) => {  console.log;

图片 14

然后我们进入项目中的目录,执行 node index.js
执行后看到命令行中会打印中的token了,如下所示:

图片 15

当然我们也可以设置token的过期时间,比如设置token的有效期为1个小时,如下代码:

图片 16

// 生成一个tokenconst jwt = require('jsonwebtoken');const secret = 'abcdef';// 设置token为一个小时有效期let token = jwt.sign({  name: 'kongzhi',  exp: Math.floor(Date.now + }, secret, (err, token) => {  console.log;

图片 17

5.2 jwt.verify(token, secretOrPrivateKey, [options, callback])

该方法是验证token的合法性

比如上面生成的token设置为1个小时,生成的token为:

'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoia29uZ3poaSIsImlhdCI6MTU0Mzc2MjYzOSwiZXhwIjoxNTQzNzY2MjM5fQ.6idR7HPpjZIfZ_7j3B3eOnGzbvWouifvvJfeW46zuCw'

下面我们使用 jwt.verify来验证一下:

图片 18

const jwt = require('jsonwebtoken');const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoia29uZ3poaSIsImlhdCI6MTU0Mzc2MjYzOSwiZXhwIjoxNTQzNzY2MjM5fQ.6idR7HPpjZIfZ_7j3B3eOnGzbvWouifvvJfeW46zuCw';const secret = 'abcdef';jwt.verify(token, secret, (error, decoded) => {  if  {    console.log(error.message);  }  console.log;});

图片 19

执行node index.js 代码后,生成如下信息:

图片 20

现在我们再来生成一个token,假如该token的有效期为30秒,30秒后,我再使用刚刚生成的token,再去使用
verify去验证下,看是否能验证通过吗?(理论上token失效了,是不能验证通过的,但是我们还是来实践下)。如下代码:

图片 21

// 生成一个tokenconst jwt = require('jsonwebtoken');const secret = 'abcdef';// 设置token为30秒的有效期let token = jwt.sign({  name: 'kongzhi',  exp: Math.floor(Date.now + 30}, secret, (err, token) => {  console.log;

图片 22

在命令行中生成 jwt为:
‘eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoia29uZ3poaSIsImV4cCI6MTU0Mzc2MzU1MywiaWF0IjoxNTQzNzYzNTIzfQ.79rH3h_ezayYBeNQ2Wj8fGK_wqsEqEPgRTG9uGmvD64’;

然后我们现在使用该token去验证下,如下代码:

图片 23

// 生成一个tokenconst jwt = require('jsonwebtoken');const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoia29uZ3poaSIsImV4cCI6MTU0Mzc2MzU1MywiaWF0IjoxNTQzNzYzNTIzfQ.79rH3h_ezayYBeNQ2Wj8fGK_wqsEqEPgRTG9uGmvD64';const secret = 'abcdef';jwt.verify(token, secret, (error, decoded) => {  if  {    console.log(error.message);  }  console.log;});

图片 24

执行命令,如下所示:

图片 25

如上可以看到token的有效期为30秒,30秒后再执行的话,就会提示jwt过期了。

5.3 jwt.decode(token, [, options])
该方法是 返回解码没有验证签名是否有效的payload。

相关文章

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注