JWT
什么是JWT
JSON Web Token(简称 JWT)是目前最流行的跨域认证解决方案。 jwt.io
是一种认证授权机制。
JWT 是为了在网络应用环境间传递声明而执行的一种基于 JSON 的开放标准(RFC 7519)。
JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。比如用在用户登录上。
可以使用 HMAC 算法或者是 RSA 的公/私秘钥对 JWT 进行签名。因为数字签名的存在,这些传递的信息是可信的。
JWT 由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
- 头部(Header):包含了关于生成该 JWT 的信息以及所使用的算法类型。
- 载荷(Payload):包含了要传递的数据,例如身份信息和其他附属数据。
- 签名(Signature):使用密钥对头部和载荷进行签名,以验证其完整性。
JWT的优缺点
- 优点:
- 无需在服务器上存储令牌。去中心化,无状态,便于分布式系统使用
- 基本信息可以直接放在token中,存放在客户端。 userid,name,role
- 缺点:
- 服务端不能主动让token失效
- payload的数据量
JWT 应用场景
常见的 JWT 应用常见有 JWT 授权和信息交换:
- 授权:JWT 被应用最多的场景,用户登录后服务端响应一个 JWT,后续的请求都携带 JWT内容,以此验证用户身份。使用 JWT 可以进行单点登录,可以跨域。
- 信息交换:因为 JWT 需要使用密钥进行签名,因此使用 JWT 安全的传输信息也是一个好方法,签名可以确保消息发送人没有问题,确保消息没有被篡改。
netcore实践
生成、解码jwt token
1 | using Microsoft.IdentityModel.Tokens; |
Program调用
1 | using jwt.console; |
netcore完整的使用示例
- 添加依赖包 安装以下 NuGet 包,以便支持 JWT 身份验证:
1
NuGet\Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 6.0.35
- 添加JWT配置 appsettings.json
1
2
3
4"JwtConfig": {
"SecretKey": "sdfas344gui*&*@!)@Y$IU@UI12fzgh2",
"ExpireMinutes": 60
} - 创建生成jwt token类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace jwt.api
{
/// <summary>
/// JwtSecurityTokenHandler
/// System.IdentityModel.Tokens.Jwt 和 Microsoft.IdentityModel.Tokens
/// </summary>
public class JwtTokenGenerator
{
private readonly string _key;
private readonly IOptions<JwtConfig> _options;
public JwtTokenGenerator(IOptions<JwtConfig> options)
{
_options = options;
_key = _options.Value.SecretKey;
if (_key.Length != 32) throw new ArgumentException("Key length must be 32 bytes.");
}
public string GenerateToken(string username)
{
var keyBytes = Encoding.UTF8.GetBytes(_key);
var secKey = new SymmetricSecurityKey(keyBytes);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[] {
new Claim(ClaimTypes.Name, username),
new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString())
}),
Expires = DateTime.UtcNow.AddMinutes(_options.Value.ExpireMinutes),
SigningCredentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
} - 配置 JWT 身份验证
1 | using jwt.api; |
- 登录控制器 (AuthController.cs):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49using Microsoft.AspNetCore.Mvc;
namespace jwt.api.Controllers
{
[]
[]
public class AuthController : ControllerBase
{
private readonly JwtTokenGenerator _tokenGenerator;
public AuthController(JwtTokenGenerator tokenGenerator)
{
_tokenGenerator = tokenGenerator;
}
[]
public IActionResult Login([FromBody] LoginModel model)
{
if (model.Username == "testuser" && model.Password == "password") // 这里你可以加入你的用户验证逻辑
{
var token = _tokenGenerator.GenerateToken(model.Username);
return Ok(new { token });
}
return Unauthorized();
}
}
public record LoginModel(string Username,string Password);
}
```
6. 受保护的 API (ValuesController.cs):
```C
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace jwt.api.Controllers
{
[]
[]
[] // 添加授权
public class ValuesController : ControllerBase
{
[]
public IActionResult GetValues()
{
return Ok(new string[] { "value1", "value2" });
}
}
} - 调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@host = http://localhost:5123
POST {{host}}/api/auth/login
Content-Type: application/json
{
"username":"testuser",
"password":"password"
}
###
GET {{host}}/api/values
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6InRlc3R1c2VyIiwibmFtZWlkIjoiNjkzOGYyZTctMDcwOC00N2M1LWI1ZjAtN2I2ZDFlMTA3MGQwIiwibmJmIjoxNzI5MTQ2Mzg2LCJleHAiOjE3MjkxNDk5ODYsImlhdCI6MTcyOTE0NjM4Nn0.JwjlPsyjOvm3DyyJrVfGqmyLLXt-CzSd877WhHJLGFQ