token是服务端通过加密编码等方式处理的结果返回给客户端,然后客户端每次请求都会带上这个信息,从而让服务端对此信息解密后就知道用户是谁了。
客户端将token保存在Cookie或者localStorage里面,以后客户端发出的所有请求都会携带这个token令牌。
token可以放在cookie里,但是会导致不能跨域。最好的做法是放在 http Header的Authorization字段中:
Authorzation: Bearer Token

登录流程

  • 用户向服务器发送用户名和密码登录系统。
  • 身份验证服务响应并返回签名的token,上面包含了用户是谁的内容。
  • 用户以后每次想后端发送请求都会在Header中带上token。
  • 服务端接收请求检查token信息并解密获取用户的相关信息。

为什么Cookie无法防止CSRF攻击,而Token可以?

CSRF(跨站点伪造请求),就是使用用户的身份去发送一些对你不友好的请求。
比如: 用户登录某网上银行,然后来到网上银行的帖子区,看到一个帖子下面有个链接写着“科学理财,年盈利率过万”,然后用户好气的点开这个链接,结果发现自己的账户少了1w元。这是怎么回事,原来是黑客在链接中藏了一个请求,这个请求直接利用用户的身份给银行发送了一个转账请求,也就是通过cookie向银行发出请求。

因为在进行Session认证的时候,我们一般使用Cookie来存储SessionId,当我们登陆后后端生成一个SessionId放在Cookie中返回给客户端,服务端通过Redis或者其他存储工具记录保存这个SessionId,客户端每次请求都会带上这个SessionId,服务端通过这个SessionID来标示用户信息。所以如果此时黑客通过cookie拿到了SessionId就可以代替用户的身份访问系统了。

Session认证中Cookie中的SessionId是由浏览器发送到服务端的,借助这个特性,攻击者可以通过让用户误点攻击连接,达到攻击的效果。

但是如果使用token的话,就不会存在这个问题。在我们登陆成功获得token之后,一般会选择存放在local storage中。然后在前端通过某些方式会给每个发送到后端的请求加上这个token,这样就不会出现CSRF的漏洞。因为,即使有个你点击了非法连接发送了请求带服务端,这个非法请求是不会懈怠token的,所以这个请求就是非法的。

Token的优点

1、可以通过url,post请求参数或者http头参数发送,因为数据量小,传输速度也很快。
2、token信息串里面自包含了用户所需要的一些信息,可以避免多次查询数据库。
3、因为token是以json的形式保存在客户端的,所以JWT是跨语言的。
4、不需要在服务端保存会话信息,特别适用于分布式微服务。

JWT的结构

Header

描述JWT的元数据。定义了签名算法以及Token的类型,最后需要通过Base64URL算法转成字符串。

  1. {
  2. "alg": "HS256",
  3. "typ": "JWT"
  4. }

Payload

负载:用来存放实际需要传递的数据
默认情况下JWT是不加密的,任何人只要在网上进行Base64解码就可以读到信息,所以一般不要将秘密信息放在Payload这里。这个对象也要用Base64URL算法转成字符串。

Signature

服务器通过 HeaderPayload 、和一个密钥 Secret 使用Header里面指定的签名算法生成。

Base64URL算法:Base64有三个字符 +/= ,在url里面有特殊含义,因为token可能会在url作为参数传递,所以需要替换这三个字符, + 替换为 -/ 替换为_= 被省略