JWT发展简史
JWT Token
JSON Web Token (JWT,RFC 7519 (opens new window)),是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准((RFC 7519)。
ID Token
OIDC (OpenID Connect) 协议 (opens new window)对 OAuth 2.0 协议 (opens new window)最主要的一个扩展就是 ID Token 数据结构。ID Token 相当于用户的身份凭证,开发者的前端访问后端接口时可以携带 ID Token,开发者服务器可以校验用户的 ID Token 以确定用户身份,验证通过后返回相关资源。
传统玩法
当浏览器向服务器发送登录请求时,验证通过之后,会将用户信息存入seesion中,然后服务器会生成一个sessionId放入cookie中,随后返回给浏览器。
当浏览器再次发送请求时,会在请求头部的cookie中放入sessionId,将请求数据一并发送给服务器。
服务器就可以再次从seesion获取用户信息,整个流程完毕!
通常在服务端会设置seesion的时长,例如 30 分钟没有活动,会将已经存放的用户信息从seesion中移除。
同时,在服务端也可以通过seesion来判断当前用户是否已经登录,如果为空表示没有登录,直接跳转到登录页面;如果不为空,可以从session中获取用户信息即可进行后续操作。
这种场景单体程序没有问题,即使用户量增加,可以用公用session数据库,微软基本就这样玩过。
Redis登场
为了解决效能问题,以及redis出现,于是有了redis解决登录这个问题:
将各个应用程序与内存数据库redis相连,对登录成功的用户信息进行一定的算法加密,生成的ID被称为token,将token还有用户的信息存入redis;等用户再次发起请求的时候,将token还有请求数据一并发送给服务器,服务端验证token是否存在redis中,如果存在,表示验证通过,如果不存在,告诉浏览器跳转到登录页面,流程结束。
token方案保证了服务的无状态,所有的信息都是存在分布式缓存中。基于分布式存储,这样可以水平扩展来支持高并发。
当然,现在springboot还提供了session共享方案,类似token方案将session存入到redis中,在集群环境下实现一次登录之后,每个服务器都可以获取到用户信息。
JWT 登场
JWT全称JSON Web Token,实现过程简单的说就是用户登录成功之后,将用户的信息进行加密,然后生成一个token返回给客户端,与传统的session交互没太大区别。
目的是:不用缓存数据库redis来实现用户信息的共享,以达到一次登录,处处可见的效果呢?
技术手段就是客户端携带着token,然后根据规则解析。
JWT构成
因为是标准所以,构成格式是有规则的:
三段信息用.链接 header,paylaod,signature
- 第一部分:我们称它为头部(header),用于存放token类型和加密协议,一般都是固定的;
- 第二部分:我们称其为载荷(payload),用户数据就存放在里面;
- 第三部分:是签证(signature),主要用于服务端的验证;
header 分为两部分:都是json表达式
JWT的头部承载两部分信息:
- 声明类型,这里是JWT;
- 声明加密的算法,通常直接使用 HMAC SHA256;
paylaod :
载荷就是存放有效信息的地方,这些有效信息包含三个部分:
- 标准中注册的声明;
- 公共的声明;
- 私有的声明;
其中,标准中注册的声明 (建议但不强制使用)包括如下几个部分 :
- iss: jwt签发者;
- sub: jwt所面向的用户;
- aud: 接收jwt的一方;
- exp: jwt的过期时间,这个过期时间必须要大于签发时间;
- nbf: 定义在什么时间之前,该jwt都是不可用的;
- iat: jwt的签发时间;
- jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击;
公共的声明部分: 公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。
私有的声明部分: 私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。
signature
signature = 加密( base64UrlEncode(header) + '.' + base64UrlEncode(payload) );
保护好服务端secret私钥非常重要,因为私钥可以对数据进行验证、解密!
单点登录
Single sign-on (SSO) is an authentication scheme that allows a user to log in with a single ID and password to any of several related, yet independent, software systems.
单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问所有信任的应用系统。
为何单点登录
一个公司有n多系统,每个系统有账号密码,比如几十个搞,如何搞?社交媒体有n多网站应用,各类用户和密码,很难整,有没有可能,只记住一个用户密码,其他都同行,这就是单点登录想解决的问题,衍生出各类逻辑问题,对应的就是安全,技术问题等等。
如何单点登录
有一个解决方案,我将我的身份委托给我需要使用的所有网站都信任的单一安全服务,我只需要记住这个安全服务的账号密码,所有其他网站自身不需要具备验证身份的能力,统一由安全服务确认用户身份。
这就是Single Sign On ,单点登录。
JWT实现单点登录
- 因为是标准,所以不同的语言平台都有对应的实现接口
- 需要一个公共的身份管理中心
- 管理身份和各类应用
- 分配应用和用户的关系,完成对应业务系统的身份同步
- 身份管理中心登陆后,点击业务应用,验证后,携带idtoken,跳转业务系统sso地址
- 各类应用根据jwt的规则,有对应的sso地址,用以解析IDtoken,实现业务系统的登录
- 业务系统自动跳转身份中心登录入口,重新转向业务地址
- 对应解决单点登出接口,实现各个业务应用同步