跨域认证
Session认证
提要
互联网用户认证的一般流程:
- 用户向服务器发送用户名和密码
- 服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登陆时间等。
- 服务器向用户返回一个
session_id,写入用户的Cookie - 用户随后的每一次请求,都会通过
Cookie,将session_id传回服务器 - 服务器收到
session_id,找到前期保存的数据,由此得知用户的身份
Session的问题与解决方案
session认证扩展性不好,如果是服务器集群,或者是跨域的武器导向架构,就要求session数据共享,每台服务器都能够读取session,针对这种问题一般有两种方案:
- session数据持久化,写入数据库或者别的持久层。各种服务收到请求后,都向持久层请求数据。这种方案的优点是架构清晰,缺点是工程量比较大
- 服务器不再保存session数据,所有数据都保存在客户端,每次请求都发回服务器。T
oken认证就是这种方案的代表
Token认证
是服务器产生的一串字符串,是客户端访问资源接口(API)时所需要的资源凭证,流程如下:
- 客户端使用用户名跟密码请求登录,服务器收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个token并把这个token发送给客户端
- 客户端收到token以后,会把它存储起来,比如放在
cookie里或者localStorage里 - 客户端每次向服务端请求资源的时候需要带着服务端签发的token
- 服务器收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就向客户端返回请求的数据
特点
- 基于token的用户认证是一种服务端无状态的认证方式,服务端不用存放token数据
- 用解析token的计算时间换取session的存储时间,从而减轻服务器的压力,减少频繁的查询数据库
- token完全由应用管理,所以它可以避开同源策略
JWT的使用
概述
- JWT(JSON Web Token)是一个token的具体实现方式,是目前最流行的跨域认证解决方案
- JWT的原理是,服务器认证以后,生成一个JSON对象,发回给用户,具体如下:

- 用户与服务器通信的时候,都要发回这个JSON对象。服务器完全只靠这个对象认定用户身份
- 为了防止用户篡改数据,服务器在生成这个对象的时候会加上签名
组成
JWT由三部分组成:
- Header(头部)
- Payload(负载)
- Signature(签名)
三个部分最终组合为完整的字符串,中间使用.分割: - Header.Payload.Signature

Header
- Header部分是一个JSON对象,描述JWT的元数据
1 | { |
- alg属性表示签名的算法(algorithm),默认是
HMAC SHA256(写成HS256) - typ属性表示这个令牌(token)的类型(type),JWT令牌统一写为JWT
- 最后,将上面的JSON对象使用
Base64URL算法转成字符串
Payload
- Payload部分也是一个JSON对象,用来存放实际需要传递的数据。JWT规定了7个官方字段,供选用
- iss(issuer):签发人
- exp(expiration time):过期时间
- sub(subject):主题
- aud(audience):受众
- nbf(Not before):生效时间
- iat(Issued At):签发时间
- jti(JWT ID):编号
- 注意,JWT默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分
- 这个JSON对象也要使用
Base64URL算法转成字符串
Signature
- Signature 部分是对前两部分的签名,防止数据篡改
- 首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄漏给用户
- 然后,使用Header里面指定的签名算法(默认是HMAC SHA256),按照下面的公式产生签名
1 | HMACSHA256( |
特点
- 客户端收到服务器返回的JWT以后,可以放在
cookie里或者localStorage里 - 客户端每次与服务器通信,都要带上这个JWT,可以把它放在Cookie里面自动发送,但是这样不能跨域
- 更好的做法是放在HTTP请求的头信息
Authorization字段里面,单独发送
JWT的实现(java)
- 加入依赖
1 | <!--引入jwt--> |
生成Token
1 | //七天过期 |
解析Token
1 | //解析Token |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Blog of Sof!
评论






