1.新建一個.net core2.1 基於 api 的工程,引用Microsoft.AspNetCore.Authentication.JwtBearer 包
2.新建一個Token的實體類,一個Jwt的基礎類

public class TokenModel { /// <summary> /// 用戶Id /// </summary> public long userId { get; set; } /// <summary> /// 用戶名 /// </summary> public string userCode { get; set; } /// <summary> /// 手機 /// </summary> public string phone { get; set; } /// <summary> /// 頭像 /// </summary> public string icon { get; set; } /// <summary> /// 昵稱 /// </summary> public string userName { get; set; } /// <summary> /// 身份 /// </summary> public string sub { get; set; } /// <summary> /// 角色 /// </summary> public string role { get; set; } }

/// <summary> /// 基礎配置 /// </summary> public class JwtSettings { //token是誰頒發的 public string Issuer { get; set; } //token可以給哪些客戶端使用 public string Audience { get; set; } //加密的key public string SecretKey { get; set; } //過期時間 單位:s public string ExpireTime { get; set; } }
3.在Appsetting.json中添加默認值
"JwtSettings": { "Issuer": "NinaMua", "Audience": "http://localhost:5000", "SecretKey": "NinaMua'sSecretKeyMuaMuaMua",//16位字符以上 "ExpireTime": "3600" //過期時間||單位:s }
4.新建一個類去把在appsetting設定的值變成一個可以全局引用的對象
public class AppSettingsInit { public static JwtSettings JwtSettings; /// <summary> /// 將配置項的值賦值給屬性 /// </summary> /// <param name="configuration"></param> public void Initial(IConfiguration configuration) { JwtSettings = new JwtSettings(); JwtSettings.Audience = configuration["JwtSettings:Audience"]; JwtSettings.Issuer = configuration["JwtSettings:Issuer"]; JwtSettings.SecretKey = configuration["JwtSettings:SecretKey"]; JwtSettings.ExpireTime = configuration["JwtSettings:ExpireTime"]; } }
5.去新增一個JwtTokenHelper類

public class JwtTokenHelper { public static JwtSecurityTokenHandler _jwt = new JwtSecurityTokenHandler(); /// <summary> /// 頒發JWT字符串 /// </summary> /// <param name="tokenModel"></param> /// <returns></returns> public static string IssueJwt(TokenModel tokenModel) { var encodedJwt = ""; try { var claims = new Claim[] { new Claim("userId", tokenModel.userId.ToString()), new Claim("userCode", tokenModel.userCode), new Claim("phone", tokenModel.phone), new Claim("userName", tokenModel.userName), new Claim("role", tokenModel.role), new Claim("tokenType", tokenModel.tokenType.ToString()) }; DateTime expTime = DateTime.Now.AddSeconds(Convert.ToDouble(AppSettingsInit.JwtSettings.ExpireTime)); //秘鑰 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AppSettingsInit.JwtSettings.SecretKey)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var jwt = new JwtSecurityToken( issuer: AppSettingsInit.JwtSettings.Issuer, audience: AppSettingsInit.JwtSettings.Audience, claims: claims, expires: expTime,//過期時間 signingCredentials: creds); encodedJwt = _jwt.WriteToken(jwt); } catch (Exception ex) { } if (encodedJwt != "") encodedJwt = $"{JwtBearerDefaults.AuthenticationScheme} {encodedJwt}"; return encodedJwt; } /// <summary> /// 解析jwt字符串 /// </summary> /// <param name="jwtStr"></param> /// <returns></returns> public static TokenModel SerializeJWT(string jwtStr) { var tm = new TokenModel(); JwtSecurityToken jwtToken = _jwt.ReadJwtToken(jwtStr); try { var JwtList = jwtToken.Payload; tm.userCode = JwtList["userCode"]?.ToString(); tm.userId = Convert.ToInt64(JwtList["userId"]); tm.userCode = JwtList["userCode"]?.ToString(); tm.phone = JwtList["phone"]?.ToString(); tm.userName = JwtList["userName"]?.ToString(); tm.role = JwtList["role"]?.ToString(); } catch (Exception e) { // ignored } return tm; } }
6.在startup.cs中的ConfigureServices注入依賴

public void ConfigureServices(IServiceCollection services) { #region 配置登錄授權 services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, (jwtBearerOptions) => { jwtBearerOptions.TokenValidationParameters = new TokenValidationParameters { //需要跟生成Token的信息保持一致 ValidateIssuerSigningKey = true,//驗證全局秘匙||默認True IssuerSigningKey = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(AppSettingsInit.JwtSettings.SecretKey)), ValidateIssuer = true,//驗證發布者||默認True ValidIssuer = AppSettingsInit.JwtSettings.Issuer, ValidateAudience = true,//驗證訪問者||默認True ValidAudience = AppSettingsInit.JwtSettings.Audience, ValidateLifetime = true,//驗證生命周期||默認True ClockSkew = TimeSpan.Zero }; }); #endregion services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); #region 配置Swagger services.AddSwaggerGen(c => { #region 頂部基礎信息 c.SwaggerDoc("v1", new Info { Version = "v1.1.0", Title = "WebAPI", Description = "API幫助文檔", TermsOfService = "None", Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "NinaMua", Email = "791016081@qq.com", Url = "http://www.cnblogs.com/NinaMua" } }); #endregion #region 權限驗證信息 //添加一個必須的全局安全信息,和AddSecurityDefinition方法指定的方案名稱要一致 var security = new Dictionary<string, IEnumerable<string>> { { "Bearer", new string[] { } } }; c.AddSecurityRequirement(security); c.AddSecurityDefinition("Bearer", new ApiKeyScheme { Description = "格式|Bearer {token}", Name = "Authorization",//jwt默認的參數名稱 In = "header",//jwt默認在請求頭中存放Authorization信息 Type = "apiKey" }); #endregion #region 添加讀取注釋服務 //添加對控制器的標簽(描述)通過對SwaggerDocTag添加備注 //c.DocumentFilter<SwaggerDocTag>(); var basePath = AppDomain.CurrentDomain.BaseDirectory; var apiXmlPath = Path.Combine(basePath, "TestApi.xml"); if (System.IO.File.Exists(apiXmlPath)) c.IncludeXmlComments(apiXmlPath, true);//控制器層注釋(true表示顯示控制器注釋) var entityXmlPath = Path.Combine(basePath, "TestEntity.xml"); if (System.IO.File.Exists(entityXmlPath)) c.IncludeXmlComments(entityXmlPath);//實體類注釋 #endregion }); #endregion }
7.在startup.cs中的Configure注入中間件

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseHsts(); } app.UseHttpsRedirection(); app.UseAuthentication();//配置授權 loggerFactory.AddNLog();//添加NLog env.ConfigureNLog("nlog.config");//讀取Nlog配置文件 #region Swagger app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1"); }); #endregion app.UseMvc(); }
8.在api接口上加上權限認證[Authorize]

[Route("api/")] public class LoginController : BaseApiController { public ILogger<LoginController> logger; /// <param name="_logger">日志</param> public LoginController(ILogger<LoginController> _logger) { logger = _logger; } /// <summary> /// 登錄 /// </summary> /// <returns></returns> [Route("Login")] [HttpGet] public ResponseMessage Login() { ///用戶是否存在/// TokenModel temp = new TokenModel(); temp.userName = "系統管理員"; temp.userCode = "system"; temp.role = "Admin"; temp.phone = ""; temp.icon = ""; var result = JwtTokenHelper.IssueJwt(temp); if (result != "") return Success(result); else return CustomizeResponse(100, "登錄失敗"); } /// <summary> /// 退出 /// </summary> /// <returns></returns> [HttpGet] [Route("SignOut")] [Authorize] public string Exit() { return "1111"; } }
9.測試
在沒有token的請求中~請求接口401
拿到token后放在全局之中