JWT的使用

登录验证

用户登录和鉴权的重要性不言而喻
由于HTTP请求无状态的特性,为了节省运算资源,有必要(?)提供一套登录机制,在验证通过后、一段时间内对需要登录的操作放行
常用的方法有:Session机制,JWT机制和OAuth机制 cookie-session

Session

Session,会话。在用户登录后,服务器存储用户会话的相关信息,并为客户端指定一个访问凭证,如果有客户端凭此凭证发出请求,则在服务端存储的信息中取出用户相关登录信息并使用
服务端返回的凭证常存储于Cookie中。此时Cookie与SessionStorage和LocalStorgae并无太多不同,是一种存储的载体,本质上来说,存在Cookie中的内容也可以存在别处

基于Session和其他服务器存储凭证的鉴权机制有一个问题,对分布式系统比较不友好
如果用户的请求会到达两台服务器上,那么如果其中一台没有登录过,鉴权就会失败
解决这个有数种方法:
一是存储的数据库是分布式的,访问任意一台机器时,实际上都会从分布式的数据库(数据中心)调取凭证
二是通过流量分发,保证同一SessionId的用户,每次请求都会到同一台服务器(数据库)上

JWT

JWT是一种无状态的鉴权机制。将用户登录后的一些信息(比如用户Id)和过期时间等信息存储在一个加密过的字符串中,当服务器收到请求的时候,进行解密并直接使用信息
JWT的组成:使用base64编码描述jwt的头部、使用base64编码的payload,以及加密签名
我们将使用jsonwebtoken模块管理JWT
缺点,服务器无法像session一样方便地管理用户登录状态

Cookie-Session

Express的一个中间件,与JWT类似,使用签名+明文的方法在cookie当中存储session,使用sha256算法进行加密

登录

明文存储用户密码是一件很不机智的事情,包括CSDN在内的一系列组织都出现过大量用户账号密码泄露的事故,如果明文存储密码,画美不看
我们使用Node.js自带的crypto模块中的pbkdf2算法,加密用户的密码,在登录时取出密码进行比对
使用时要注意:1.不能使用pbkdf2Sync方法;2.由于该算法耗时较长,要进行异步处理,可以学习utilities或者bluebird中的promisify方法

什么是JWT
JWT, 全称是JSON Web Token,
是一种易于使用、无状态的鉴权(Authorization)方式。
简单的来说,就是

Server端把JSON数据经过加密做成token,以授权给Client端。

当Client端登录完成以后,
Server端要返回一个7天有效的token,
那么对应的Python的样例代码会是这样的:
(使用了PyJWT包:pip install pyjwt)

import time

import jwt

exp = int(time.time()) + 86400 * 7  // 失效时间
user = 'liriansu'  // 用户表示
key = 'hunter2'  // 密钥
payload = {'exp': exp, 'user': user}  // JSON 数据
token = jwt.encode(payload, key)

print(token)
// token可能会长这样子
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.EoKoMCjq_zGqUg5HDfqw4EN7EiG6gMjkUZle0uGJDGU

关于hunter2也有个梗:弱密码hunter2

然后Client端每次在authorization header或者是query string里带上token。
Server端收到请求的时候,

用payload = jwt.decode(token, key)验证权限就行了。

验证通过以后,payload中就是整个JSON数据。
理论上你可以往token payload里塞任何_非敏感_数据。

所以综合来说,
假如使用JWT作为鉴权方式,
有以下几个特性:

Client端不用管任何加密/解密,只用存token,在请求里面带上就行了。
Server端可以实现不依赖外部存储鉴权,所有的数据都丢在token里。
也就是说鉴权这一步不需要File/MySQL/Redis之类的数据库,也能知道用户身份。
因为token带失效时间,所以需要在失效前/后再刷新token。

关于JWT的更多说明,实质上就是用个JSON数据当token,
这破token真的安全吗?能伪造吗?这个问题很尖锐,难以正面回答。

首先token/key泄漏了, 后果基本是跟其它鉴权方式一样严重。 其次JWT可以选择合适的加密方式, 加上合适的key是基本伪造不了的。
还有就是在JWT之外, 一定要用HTTPS! 不用JWT相当于没有门禁, 不用HTTPS基本是不穿内裤了。。。

简单的来说,JWT是由以下三部分组成的:

第一部分指定了加密算法(alg)和token类型(typ)。
第二部分就是我们定义的payload。
第三部分是由加密算法产生的签名。

我去,那token里的信息就是明文的啊?
是的。
所以token里不要带任何敏感信息。

文档上把payload里带的信息叫Claim,
有这么几个可选的Claim:

iss: Issuer, 签发方。
比如这个token是微信签发的,
那么可以是{'iss': 'wechat'}
aud: Audience, 接收方。
比如王者荣耀想用微信登录,
那么可以是{'aud': 'king-of-glory'}
exp: Expiration Time, 失效时间。
使用的是整形Unix时间戳,
关于时间戳可以看看《互联网上的日期和时间》
RFC7519里面还有一点很好玩,
就是上面每一个Claim最后都加了一句Use of this claim is OPTIONALRFC2119还定义过啥叫OPTIONAL

也就是说我们可以往payload里丢任何东西。
只要符合这种加密/解密/鉴权的方式,
我们都可以说“我们用了JWT”。

那token会不会很大?
有可能会。

所以payload里的东西能少则少,

还有就是传输JWT的时候,
相较于放query string里,
更推荐放在Request Headers里面。

下面就用个简单的表格来对比一下_我了解的_几种鉴权方式吧:

JWT, OAuth, Session, Hawk

在这里插入图片描述

JWT全称叫JSON Web Token,

小心别写了类似jwt_token这样的变量名了(语义重复)。
RFC7519还定义了JWT读起来是类似于jot的发音。
然而实际中交流都会说JWT(怕听不懂)。
JWT说是说用同一个key就行了,
不过我们在项目实际中还是根据不一样的user用了不一样的key。
(同时也用了数据库)
假如payload里带了失效时间,
理论上JWT签发后是不会失效的,
也就是Server端管理不了这些token。
(所以可以加个数据库来管)
用JWT想做“记住登录状态”这个功能的话,
可以设定token失效期比如是7天,
然后用户每天登录的时候刷一次token。
这样除非用户一周内都没登录,
才会请求重新登录。

Hertz JWT 使用通常涉及到在 API 开发中对访问控制、身份验证和授权的管理。JWT (JSON Web Token) 是一种开放标准,用于安全地传输数据作为令牌,并可以在客户端和服务端之间进行验证。当结合 Hertz 框架使用时,可以有效提升 RESTful API 的安全性。 ### Hertz 中 JWT 的应用 1. **身份验证**:通过 JWT 提供了一个自包含的身份认证机制,允许客户端一次性携带身份信息,在请求过程中不需要再次提供凭证。 2. **权限控制**:JWT 可以携带用户角色或其他授权信息,服务端可以根据这些信息做出相应的访问决策。 3. **状态无状态性**:由于 JWT 是自包含的,它消除了对会话存储的需求,使得应用程序更易于分布式部署。 4. **加密与签名**:使用哈希算法如 HMAC 或 RSA 进行签名,保证了数据的完整性和来源的可信度。 ### 实现步骤 #### 客户端生成 JWT 1. 发起一次认证请求给服务器,例如登录请求,返回包含用户名等信息的响应。 ```http POST /login HTTP/1.1 Host: example.com username=example_user&password=example_password ``` 2. 服务器验证凭据并生成 JWT,通常包括 token、过期时间等字段,并将其返回给客户端。 ```json { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", "exp": 1682797600, // 其他信息... } ``` #### 服务端验证 JWT 1. 接收到请求,从请求头(通常是 `Authorization` 字段)提取 JWT。 ```http GET /protected-resource HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ``` 2. 使用相同的密钥解码 JWT,并验证其完整性及有效性。 3. 根据 JWT 中的信息进行授权处理,如检查用户角色、过期时间等。 ### 相关问题: 1. **如何确保 JWT 在传输过程中的安全性?** 使用 HTTPS 协议保护数据传输的安全,防止中间人攻击。同时,可以采用 AES 加密或其他更高级别的加密技术来进一步增强安全性。 2. **如何在 Hertz 框架中集成 JWT 验证机制?** 可以使用第三方库(如 gjwt)简化 JWT 验证的过程,或者自定义实现验证逻辑。这通常涉及拦截 HTTP 请求,读取 JWT使用预设的密钥进行解码和验证。 3. **JWT 的生命周期管理有哪些注意事项?** - 确保设置合理的过期时间,避免长时间有效性的 JWT 被滥用。 - 定期清理无效或已撤销的 JWT,减少资源消耗和潜在的风险。 - 对敏感操作如账户更改密码等,考虑使用短生命周期的刷新令牌而非原始的访问令牌。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Supernova_gu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值