浅谈JWT

一、JWT简介

        JWT(JSON WEB TOKEN)是一个基于JSON的公开规范(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息使用了数字签名,可以被验证与信任。

二、应用场景

  • Authorization(授权):JWT最常见的应用场景,一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
  • Information Exchange (信息交换) : JWT也可用于在各方之间安全的传输信息 。因为JWT使用了数字签名。例如,使用公钥/私钥对,就可对发送人加以验证。另外,签名是使用请求头和求求内容计算得到的,因此还可以验证内容没有被篡改。

三、JWT的结构

    JSON Web Token由三部分组成,它们之间用圆点(.)连接。这三部分分别是:

  • Header
  • Payload
  • Signature
    一个典型的JWT的形式如下所示:
aaaa.bbbbbbbbbb.cccccc

    具体到每一部分:

1. Header

        Header典型的由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)。

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

        然后,用Base64对这个JSON编码就得到JWT的第一部分.

2. Payload

        JWT的第二部分是payload,它是关于实体(通常是用户)和其他数据的声明。声明有三种类型: registered, public 和 private。

  • Registered claims : 这里有一组预定义的声明,使用时推荐,但不强制。比如:iss (issuer 发布者), exp(expiration time 有效期), sub (subject 主题), aud (audience)等。
  • Public claims : 此类型声明可以随意定义。
  • Private claims : 不属于公开或者注册的声明,用在各方约定好并同意在各方之间共享信息所使用的声明。
    一个示例:
{
    "exp":1625309676,
    "user_name":"liuzhihao",
    "jti":"2ddc8367-b4ba-448b-a282-c52cc04c289d",
    "client_id":"browser",
    "scope":[
        "all"
    ],
    "ip":"172.21.72.116"
}

      用Base64对Payload这个JSON编码就得到JWT的第二部分。
      由于base64可被解码因而被获取到所包含的信息,因此不建议在payload或header中放置敏感信息,除非它们是加密的。

3. Signature

      将编码过的header与编码过的payload使用header所声明的算法名称对它们签名,即可得到第三部分。
     格式示例:

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

     签名用于验证消息在传递过程中有没有被更改,而且对于使用私钥签名的token,它还可以验证JWT的发送方的身份。
     生成一条完整的JWT示例:
在这里插入图片描述

四、JWT的使用

       在认证时,当用户用他们的凭证成功登录以后,会获取到一个返回的JWT。此后,Token就是用户凭证了,但必须小心防止出现安全问题。一般而言,Token有效期不应超过你需要使用它的时间。
       无论何时用户想要访问受保护的路由或者资源的时候,用户代理(通常是浏览器)都应该带上JWT。通常JWT放在Authorization header中,用bearer schema。
header通常为这种形式:

Authorization: Bearer

       服务器上的受保护的路由将会检查Authorization header中的JWT是否有效。如果有效,则用户可以访问受保护的资源。如果JWT包含着足够多的必要的求取数据,那么就可以减少服务端去数据库查询的很多操作。

       如果token是在授权头(Authorization header)中发送的,那么跨源资源共享(CORS)将不会成为问题,因为它不使用cookie。

五、 基于Token的身份认证 与 基于服务器的身份认证

1.基于服务器的身份认证

HTTP协议是无状态的。也就是说,我第一次登陆时已经认证了一个用户,但是当我第二次登陆发送请求的时候,服务器依然不知道我是谁,我必须再次认证。

       传统的做法是将已经认证过的用户信息存储在服务器上,比如Session。用户下次请求的时候带着Session ID,然后服务器检查Session 确认用户是否认证过。

这种基于服务器的身份认证方式存在一些问题:

  • Sessions :
    每次用户认证通过以后,服务器需要创建一条记录保存用户信息,通常是在内存中,随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大。
  • Scalability : 由于Session是在内存中的,这就带来一些扩展性的问题。
  • CORS :
    当我们想要扩展我们的应用,让我们的数据被多个移动设备使用时,我们必须考虑跨资源共享问题。当使用AJAX调用从另一个域名下获取资源时,我们可能会遇到禁止请求的问题。
  • CSRF : 用户很容易受到CSRF攻击。
2.JWT与Session的异同
  • JWT和Session都是存储用户信息的载体,但是Session是存储在服务器端的,而JWT是存储在客户端的。
  • 方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销;而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。
  • Session的状态存储在服务器端,客户端只有session id;而Token的状态存储在客户端。
    在这里插入图片描述
3.基于Token的身份认证

基于Token的身份认证是无状态的,服务器中不会存储任何用户信息。

没有会话信息意味着应用程序可以根据需要扩展和添加更多的机器,而不必担心用户登录的位置。

这一实现的主要流程如下:

  1. 用户携带用户名和密码请求访问
  2. 服务器校验用户凭据
  3. 应用提供一个token给客户端
  4. 客户端存储token,并且在随后的每一次请求中都带着它
  5. 服务器校验token并返回数据

注意:

  • 每一次请求都需要token
  • Token应该放在请求header中
  • 我们还需要将服务器设置为接受来自所有域的请求,用Access-Control-Allow-Origin: *

在这里插入图片描述

4.Token的优势
  • 无状态和可扩展性:Tokens存储在客户端。完全无状态,可扩展。我们的负载均衡器可以将用户传递到任意服务器,因为在任何地方都没有状态或会话信息。
  • 安全:Token并不是Cookie,每次请求的时候Token都会被发送。而且,由于没有Cookie被发送,还有助于防止CSRF攻击。即使在你的实现中将token存储到客户端的Cookie中,这个Cookie也只是一种存储机制,而非身份认证机制。没有基于会话的信息可以操作,因为我们没有会话。

还有一点,token在一段时间以后会过期,这个时候用户需要重新登录。这有有利于安全性。还有一个概念叫token撤销,它允许我们根据相同的授权许可使特定的token甚至一组token无效。

5. JWT与OAuth的区别
  • OAuth2是一种授权框架 ,JWT是一种认证协议
  • 无论使用哪种方式切记用HTTPS来保证数据的安全性
  • OAuth2用在使用第三方账号登录的情况(比如使用weibo, qq, github登录某个app),而JWT是用在前后端分离, 需要简单的对后台API进行保护时使用。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值