jwt使用小结(1)--概念详解

    xiaoxiao2022-07-02  96

    一、JWT 组成

    JWT 全称 JSON Web Tokens , 是一个非常轻巧的规范。这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息. JWT 默认是不加密的,任何人都可以解密出来读到,所以不要把秘密信息放在里面。 它的两大使用场景是: 认证 和 数据交换

    jwt由三部分组成:

    Header(头部)Payload(负载)存放的一些数据在这部分,但不是私密数据。服务器获得解析会得到Signature(签名)

    1.Header

    加粗样式部分是一个json对象,通常如下的样子,使用的时候需要 Base64URL 算法转成字符串。

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

    alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。

    2.Payload

    如下官方规定了的7个字段,其他需要更多字段可以自定义。使用的时候需要 Base64URL 算法转成字符串。 其中包含claims。claims是关于实体(常用的是用户信息)和其他数据的声明,claims有三种类型: registered, public, and private claims。

    **Registered claims:**不强制,但是推荐使用, iss (发行人), exp(到期时间), sub(主题), aud(观众)等;Public claims: 自定义claims,注意不要和JWT注册表中的属性冲突即可,常放的是用户信息。Private claims: 自定义的claims,用于在同意使用这些claims的各方之间共享信息,它们既不是Registered claims,也不是Public claims。 官方的属性字段:iss (issuer):签发人exp (expiration time):过期时间sub (subject):主题 (JWT所面向的用户)aud (audience):受众 (接收JWT的一方)nbf (Not Before):生效时间 ( 在xxx日期之间,该JWT都是可用的)iat (Issued At):签发时间jti (JWT ID):编号 (JWT的唯一身份标识)

    如下自定义字段

    { "sub": "1234567890", "name": "John Doe", "url": "xxxxx" }

    3.Signature

    Signature 部分是对前两部分的签名,防止数据篡改。 需要自己在服务器指定一个密钥(secret),并且这个密钥只保存在服务器,使用第一部分Header里面指定的算法(默认是HMAC SHA256 简称HS256),按照下面公式产生签名

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

    最后 算出签名Signature 以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。 如下格式

    JWT 的几个特点 (1)JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。

    (2)JWT 不加密的情况下,不能将秘密数据写入 JWT。

    (3)JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。

    (4)JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

    (5)JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

    (6)为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

    二、JWT 工作原理

    因为JWT 的 Token 相当是明文,是可以解密的,任何存在 payload 的东西,都没有秘密可言,所以隐私数据不能签发 token。

    第一步: payload 中有个标准字段 exp,明确表示了这个 token 的过期时间. 服务端解析拿客户端传来的token,拿到payload里面的信息第二步: 把解密出来过期时间exp的时间与服务器系统时间作对比,过期则拒绝访问。第三步: 在没有过期的情况下,服务器端执行一次 signature= 加密算法(header + “.” + payload, 密钥); 比对服务器执行得到的signature 与客户端上传的signature是否一致,如果不一致则拒绝访问,如一致返回对应的请求信息。

    注意:一般是第一步获取userId这类用户基本的识别信息,第二步确实是否过期,第三步是防止Token被串改

    *安全性相关

    如果加强 JWT 的安全性? 总结以下几点:

    一定要保存好服务端的secret,防止泄露给客户端。

    缩短 token 有效时间 使用安全系数高的加密算法 token 不要放在 Cookie 中,有 CSRF 风险 使用 HTTPS 加密协议 对标准字段 iss、sub、aud、nbf、exp 进行校验 使用成熟的开源库,不要手贱造轮子 特殊场景下可以把用户的 UA、IP 放进 payload 进行校验(不推荐)

    最新回复(0)