一个Asp.Net Core Api 程序,程序的功能大概有两个:模拟验证用户登录,权限认证模块给用户颁发Jwt,用户带token来调用Api资源。
首先简单介绍一下JWT的数据结构,JWT由头部、载荷与签名这三部分组成,中间以「.」分隔。
头部以 JSON 格式表示,用于指明令牌类型和加密算法。形式如下,表示使用 JWT 格式,加密算法采用 HS256。
{
"alg": "HS256",
"typ": "JWT"
}
载荷用来存储服务器需要的数据,比如用户信息,要注意的是重要的机密信息最好不要放到这里,比如密码。
{
"name": "zhouxieyi",
"introduce": "a test token"
}
另外,JWT 还规定了 7 个字段供开发者选用。
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
签名使用HMACSHA256算法计算得出,这个方法有两个参数,前一个参数是 (base64 编码的头部 + base64 编码的载荷)用点号相连,后一个参数是自定义的字符串密钥,密钥不要暴露在客户端。
我们在appsettings.json中存放了我们自定义的token信息如下:
"tokenManagement": {
"issuer": "webapi.cn",
"name": "zhouxieyi",
"introduce": "a test token",
"audience": "WebApi",
"secret": "qwertyuiopasdfghjklzxcvbnm",
"accessExpiration": 30,
"refreshExpiration": 60
}
下一步配置StartUp.cs,将身份认证中间件加入引用,并引入NuGet:Microsoft.AspNetCore.Authentication.JwtBearer,在Configure中配置好服务。
创建用户User,UserService来模拟用户登录,这里我们假使所有的用户都合法。用户通过校验后,利用AuthenticationService颁发token,根据这两步逻辑,我们编写接口和控制器来完成。
代码如下:
StartUp.cs
AuthenticationService
UserService
AuthenticationController
WeatherForecastController
Models运行程序,使用PostMan测试:
先利用用户获取Token

设置Token类型,输入我们刚刚获取的Token,访问Api成功获取数据。

HttpClient:
创建一个Console程序,创建HttpClient,HttpClient类实例充当发送 HTTP 请求的会话。每个 HttpClient 实例都使用其自己的连接池,并从其他实例所执行的请求隔离其请求 HttpClient。
利用.NET Json处理拓展包:using System.Net.Http.Json,可以很方便的带Json对象发送请求。具体逻辑流程是使用client带用户信息请求token,获取成功后将token绑定到Header中:Authorization : Bearer + token即可,在请求Api即可获取资源。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
namespace any
{
public class Program
{
static async Task Main(string[] args)
{
var client = new HttpClient();
var uri = new Uri("https://localhost:5001");
var user = new User
{
UserName = "client",
PassWord = "123321"
};
//利用SendAsync发送请求,在Request中设置Content或Header传入。
//var postRequest = new HttpRequestMessage(
// HttpMethod.Post,
// uri.AbsoluteUri + "api/Authentication/RequestToken")
//{
// Content = JsonContent.Create(user),
//};
//var response = await client.SendAsync(postRequest);
//使用PostAsJsonAsync传递json
var response = await client.PostAsJsonAsync(uri.AbsoluteUri + "api/Authentication/RequestToken", user);
var token = await response.Content.ReadAsStringAsync();
Console.WriteLine($"token: {token}");
//设置Header
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
var result = await client.GetStringAsync(uri.AbsoluteUri + "api/WeatherForecast");
Console.WriteLine($"string result: {result}");
var jsonResponse = await client.GetAsync(uri.AbsoluteUri + "api/WeatherForecast");
var jsonObjs = await jsonResponse.Content.ReadFromJsonAsync<List<WeatherForecast>>();
if (jsonObjs != null)
{
foreach (var weatherForecast in jsonObjs)
{
Console.WriteLine($"Date is {weatherForecast.Date}, is {weatherForecast.Summary} day");
}
}
}
}
}
result:

