1、新建ASP .NET Core Web Api ,名称Linjie.JWT
2、右键项目 NuGet程序包管理工具 添加Microsoft.AspNetCore.Authentication.JwtBearer,System.IdentityModel.Tokens.Jwt
3、添加类 JWTHelper,代码如下:
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
namespace Linjie.JWT
{
public static class JWTHelper
{
/// <summary>
/// 产生JWT Token
/// </summary>
/// <returns></returns>
public static string GetToken()
{
byte[] key = System.Text.Encoding.UTF8.GetBytes("这是一个证书签名的密钥");
SecurityKey securityKey = new SymmetricSecurityKey(key);
SigningCredentials signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
JwtSecurityToken jwtSecurityToken = new JwtSecurityToken(
issuer: "这是发布者",
audience: "受众,接受jwt token的对象",
claims: GetClaims(),
notBefore: DateTime.Now,
expires: DateTime.Now.AddMinutes(1),
signingCredentials: signingCredentials);
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
string token = tokenHandler.WriteToken(jwtSecurityToken);
return token;
}
/// <summary>
/// 获取声明信息
/// </summary>
/// <returns></returns>
public static List<Claim> GetClaims()
{
List<Claim> ClaimList = new List<Claim>
{
new Claim(ClaimTypes.Name, "张三"),
new Claim(ClaimTypes.Role, "admin"),//这个用于角色判断的,控制器种的权限控制
new Claim(ClaimTypes.Email, "117542969866@163.com"),
new Claim(ClaimTypes.MobilePhone, "12345678901")
};
return ClaimList;
}
}
}
4、添加类 TokenController,代码如下:
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Linjie.JWT
{
[ApiController]
[Route("[controller]")]
public class TokenController : ControllerBase
{
[HttpGet]
public string Get()
{
var token = JWTHelper.GetToken();
return token;
}
[HttpGet("{id}")]
public string Get(int id)
{
var rng = id + JWTHelper.GetToken();
return rng;
}
}
}
5、修改类 Startup,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
namespace Linjie.JWT
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddAuthentication(options =>
{//设置认证的授权类型
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(option =>
{
option.TokenValidationParameters = new TokenValidationParameters() //设置token的验证
{
ValidateIssuer = true,
ValidIssuer = "这是发布者",
ValidateAudience = true,
ValidAudience = "受众,接受jwt token的对象",
ValidateLifetime = true,
RequireExpirationTime = true,
ClockSkew = TimeSpan.Zero,
IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes("这是一个证书签名的密钥"))
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();//启用身份认证 认证
app.UseAuthorization();//启用权限 授权
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
6、运行项目,获取token,代码如下:
打开浏览器输入:https://localhost:5001/token
或者使用postman 请求地址,也可以,如下图
7、解析token,
获取Token值后可以使用https://jwt.io/ 来解析,看看token里面包含哪些信息,解析出来的包括header,payload,signature
token包括三部分 header.payload.signature
1、token是一个很长的字符串,中间用点(.)分隔成三个部分。注意,JWT内部是没有换行的,并且都使用Base64编码
2、JWT token的三个部分依次如下。Header(头部)、Payload(负载)、Signature(签名)
Header
Header部分是一个JSON对象,描述JWT最基本的信息,例如,其类型及签名所用的算法等。通常是下面的样子
例子:
{
"alg": "HS256",
"typ": "JWT"
}
注:
alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);
typ属性表示这个令牌(token)的类型(type),JWT令牌统一写为JWT。然年将上面的JSON对象使用Base64URL算法转成的Base64字符串。
Payload
Payload部分也是一个JSON对象也是使用Base64URL算法转成的Base64字符串,用来存放实际需要传递的数据。JWT规定了7个官方字段,供选用。
JWT规定了7个官方字段
iss (issuer) 该JWT的签发者
aud (audience): 接受该JWT的一方
iat (Issued At) 签发时间
nbf (Not Before) 生效时间
exp (expiration time) 过期时间(为一个UNIX时间戳)
sub (subject) 该JWT所面向的用户
jti (JWT ID) 编号
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
{
"abc": "1234567890",
"name": "Jckxiongsi",
"admin": true
}
完整例子:
{
"iss":"issuer",
"aud":"audience",
"sub":"jwt sub",
"iat":"2020-1-2 08:09:09",
"nbf":"2020-1-2 10:10:00",
"exp":"2020-1-2 10:11:00",
"abc": "1234567890",
"name": "Jckxiongsi",
"admin": true
}
注意,JWT默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。
签名Signature
将上面的header和payload两个部分编码后的base64字符串都用点号连接在一起(头部在前),
就形成了要加密的base64,如base64UrlEncode(header) + "." + base64UrlEncode(payload)
例如:headerbase64.payloadbase64,将上面拼接完的字符串用HS256算法进行加密。
在加密的时候,需要提供一个密钥(secret),加密后的内容为headerpayloadbase64这一部分又叫做签名。
最后将这一部分签名也拼接在被签名的字符串后面,这样就得到了一个token了
完整的JWT:headerbase64.payloadbase64.headerpayloadbase64,
加密如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
具体解析可以访问地址 https://jwt.io/
龙腾一族至尊龙骑