解析出的 Token 是一个 ClaimsPrincipal 对象,将此对象给 context.User 赋值,然后在 API 中可以使用 User 实例来获取用户的信息。
在中间件中,使用下面的代码可以获取客户端请求的 Token 解析。
context.RequestServices.GetRequiredService<IAuthenticationService>().AuthenticateAsync(context, JwtBearerDefaults.AuthenticationScheme);
那么,我们如何手工从原生的 Http 请求中,解析出来呢?且看我慢慢来分解步骤。
首先创建一个 TestMiddleware 文件,作为中间件使用。
public class TestMiddleware
{
private readonly RequestDelegate _next;
jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
public TestMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
// 我们写代码的区域
// 我们写代码的区域
await _next(context);
}
}
2.1.1 从 Http 中获取 Token
下面代码可以中 http 请求中,取得头部的 Token 。
当然,客户端可能没有携带 Token,可能获取结果为 null ,自己加个判断。
贴到代码区域。
string tokenStr = context.Request.Headers["Authorization"].ToString();
Header 的 Authorization 键,是由 Breaer {Token}组成的字符串。
2.1.2 判断是否为有效令牌
拿到 Token 后,还需要判断这个 Token 是否有效。
因为 Authorization 是由 Breaer {Token}组成,所以我们需要去掉前面的 Brear 才能获取 Token。
/// <summary>
/// Token是否是符合要求的标准 Json Web 令牌
/// </summary>
/// <param name="tokenStr"></param>
/// <returns></returns>
public bool IsCanReadToken(ref string tokenStr)
{
if (string.IsNullOrWhiteSpace(tokenStr) || tokenStr.Length < 7)
return false;
if (!tokenStr.Substring(0, 6).Equals(Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme))
return false;
tokenStr = tokenStr.Substring(7);
bool isCan = jwtSecurityTokenHandler.CanReadToken(tokenStr);
return isCan;
}
获得 Token 后,通过 JwtSecurityTokenHandler.CanReadToken(tokenStr); 来判断 Token 是否符合协议规范。
将下面判断贴到代码区域。
if (!IsCanReadToken(ref tokenStr))
return ;
2.1.3 解析 Token
下面代码可以将 Header 的 Authorization 内容转为 JwtSecurityToken 对象。
(截取字符串的方式很多种,喜欢哪个就哪个。。。)
/// <summary>
/// 从Token解密出JwtSecurityToken,JwtSecurityToken : SecurityToken
/// </summary>
/// <param name="tokenStr"></param>
/// <returns></returns>
public JwtSecurityToken GetJwtSecurityToken(string tokenStr)
{
var jwt = jwtSecurityTokenHandler.ReadJwtToken(tokenStr);
return jwt;
}








