Token
什么是Token
Token:
Token是访问资源接口(API)时所需要的资源凭证,也成为令牌
传统的Token
传统的Token,例如:用户登录成功生成对应的令牌,key:令牌 ,value:userId(用户信息)
将该token存放到Redis中,返回对应的Token返回给客户端。
客户端每次访问后端请求的时候,会传递该token在请求中 (可以作为请求头传递,或者请求路径传递等),服务器端接收到该token之后,从redis中查询如果存在的情况下,则说明在有效期内,如果在Redis中不存在的情况下,则说明过期或者token错误。
Token实现认证流程
前端点击登陆,服务器验证账号密码是否正确
正确后,服务器生成令牌(生成令牌的技术有很多,比如UUID等)
将该令牌存到数据库或redis中,key是uuid(Token),value是userId
把令牌返给客户端,客户端把令牌存在cookie中。
以后请求的时候就把Token放在请求头里带上
服务端收到请求后,从redis中验证该Token是否存在
不存在,则说明用户未登录或登录过期
存在获取value内容userId。根据userId查询数据库用户信息。
如果数据库中存在userId用户,则说明认证成功,可以访问资源。
优缺点
优点
可以隐藏真实数据,适当避免明文传输
适用于分布式,解决Session共享问题
缺点
依赖Redis或数据库存储
如果不使用第三方存储,那还不如使用Session
JWT
什么是JWT
JWT:
JWT的全称是JSON WEB Token,是一种流行的跨域认证解决方案。
它将用户信息加密到Token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证Token的正确性,只要正确即通过验证。
JWT组成
JWT分3部分 —— Header、Payload、Signature
(1)Header(头) 作用:记录令牌类型、签名算法等 例如:{“alg":“HS256”,“type”,"JWT}
(2)Payload(有效载荷) 作用:携带一些用户信息 例如{“userId”:“1”,“username”:“mayikt”}
(3)Signature(签名) 作用:防止Token被篡改、确保安全性 例如 计算出来的签名,一个字符串
Header(头)
{
Typ=“jwt” —类型为jwt
Alg:“HS256” —加密算法为hs256
}
Payload(有效载荷)
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
Signature(签名)
这段是签证信息,非常非常关键的部分。
这关乎你的这个 Token 是否安全,是否能被人仿造。
一般是对 header (base64后的) 和 payload (base64后的) 这两部分的数据通过 secret(私钥)进行签名后的结果。
所以这个签名算法就非常关键了,常用的有 SHA256 和 HMAC,个人更推荐使用 RSA。
JWT加密流程
加密流程:
JWT包含三个部分: Header头部,Payload负载和Signature签名。由三部分生成Token,三部分之间用“.”号做分割。 列如 :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
1
Header 声明信息。 在Header中通常包含了两部分:type:代表token的类型,这里使用的是JWT类型。
alg:使用的Hash算法,例如HMAC SHA256或RSA。{ “alg”: “HS256”, “typ”: “JWT” } 这会被经过base64Url编码形成第一部分
Payload Token的第二个部分是荷载信息,它包含一些声明Claim(实体的描述,通常是一个User信息,还包括一些其他的元数据)
声明分三类:
1 )Reserved Claims,这是一套预定义的声明,并不是必须的,这是一套易于使用、操作性强的声明。包括:iss(issuer)、exp(expiration time)、sub(subject)、aud(audience)等
2)Plubic Claims,
3)Private Claims,交换信息的双方自定义的声明 { “sub”: “1234567890”, “name”: “John Doe”,“admin”: true } 同样经过Base64Url编码后形成第二部分
signature 使用Header中指定的算法将编码后的Header、编码后的Payload、一个secret进行加密。例如使用的是HMAC SHA256算法,大致流程类似于: HMACSHA256( base64UrlEncode(header) + “.” + base64UrlEncode(payload),secret) 这个signature字段被用来确认JWT信息的发送者是谁,并保证信息没有被修改 。
验证流程:
在头部信息中声明加密算法和常量,然后把Header使用json转化为字符串
在载荷中声明用户信息,同时还有一些其他的内容,再次使用json把在和部分进行转化,转化为字符串
使用在header中声明的加密算法来进行加密,把第一部分字符串和第二部分的字符串结合和每个项目随机生成的secret字符串进行加密,生成新的字符串,此字符串是独一无二的
解密的时候,只要客户端带着jwt来发起请求,服务端就直接使用secret进行解密,解签证解出第一部分和第二部分,然后比对第二部分的信息和客户端穿过来的信息是否一致。如果一致验证成功,否则验证失败。
特点:
三部分组成,每一部分都进行字符串的转化
解密的时候没有使用数据库,仅仅使用的是secret进行解密
Jwt使用的secret千万不能丢失
优缺点
优点
无需服务器端存放数据,减轻服务器端的压力
占用带宽比较小、跨语言
token自身包含用户信息且无法篡改,在服务(网关)中可以自行解析校验出用户信息,对认证服务器(account-svc)压力小
缺点
建议不要放敏感数据 userId、手机号码(如果非要放userId,deptId等信息,可采用rsa256算法加密)rsa256生成JWT
JWT生成之后无法修改
无法吊销令牌,只能等待令牌自身过期
Token与JWT的区别
Token需要查库验证Token 是否有效
而JWT不用查库,直接在服务端进行校验。因为用户的信息及加密信息在第二部分Payload和第三部分签证中已经生成,只要在服务端进行校验就行,并且校验也是JWT自己实现的。
常见的加密算法
————————————————
原文链接:https://blog.csdn.net/weixin_44147535/article/details/135167800