关于JWT的.net 使用(简单明了直接代码)
2024-10-21 06:23:14
首先第一步:下载插件!
在ui层---控制器所在层添加一个类
然后复制如下
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Text;
using System.IdentityModel.Tokens.Jwt; namespace JwtAuthDemo.Helpers
{
public class JwtHelpers
{
private readonly IConfiguration Configuration; public JwtHelpers(IConfiguration configuration)
{
this.Configuration = configuration;
}
public string GenerateToken(string userName, int expireMinutes = 30)
{
var issuer = Configuration.GetValue<string>("JwtSettings:Issuer");
var signKey = Configuration.GetValue<string>("JwtSettings:SignKey"); // 設定要加入到 JWT Token 中的聲明資訊(Claims)
var claims = new List<Claim>(); // 在 RFC 7519 規格中(Section#4),總共定義了 7 個預設的 Claims,我們應該只用的到兩種!
//claims.Add(new Claim(JwtRegisteredClaimNames.Iss, issuer));
claims.Add(new Claim(JwtRegisteredClaimNames.Sub, userName)); // User.Identity.Name
//claims.Add(new Claim(JwtRegisteredClaimNames.Aud, "The Audience"));
//claims.Add(new Claim(JwtRegisteredClaimNames.Exp, DateTimeOffset.UtcNow.AddMinutes(30).ToUnixTimeSeconds().ToString()));
//claims.Add(new Claim(JwtRegisteredClaimNames.Nbf, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString())); // 必須為數字
//claims.Add(new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString())); // 必須為數字
claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())); // JWT ID // 網路上常看到的這個 NameId 設定是多餘的
//claims.Add(new Claim(JwtRegisteredClaimNames.NameId, userName)); // 這個 Claim 也以直接被 JwtRegisteredClaimNames.Sub 取代,所以也是多餘的
//claims.Add(new Claim(ClaimTypes.Name, userName)); // 你可以自行擴充 "roles" 加入登入者該有的角色
claims.Add(new Claim("roles", "Admin"));
claims.Add(new Claim("roles", "Users")); var userClaimsIdentity = new ClaimsIdentity(claims); // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signKey)); // HmacSha256 有要求必須要大於 128 bits,所以 key 不能太短,至少要 16 字元以上
// https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature); // 建立 SecurityTokenDescriptor
var tokenDescriptor = new SecurityTokenDescriptor
{
Issuer = issuer,
//Audience = issuer, // 由於你的 API 受眾通常沒有區分特別對象,因此通常不太需要設定,也不太需要驗證
//NotBefore = DateTime.Now, // 預設值就是 DateTime.Now
//IssuedAt = DateTime.Now, // 預設值就是 DateTime.Now
Subject = userClaimsIdentity,
Expires = DateTime.Now.AddMinutes(expireMinutes),
SigningCredentials = signingCredentials
}; // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
var serializeToken = tokenHandler.WriteToken(securityToken); return serializeToken;
}
}
}
然后Startup进行配置
#region 开启Swagger认证
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{ Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
BearerFormat = "JWT",
Scheme = "Bearer"
}); c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] { }
}
});
#endregion
粘贴在这个位置
这段粘贴在下面的 services的位置
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
// 當驗證失敗時,回應標頭會包含 WWW-Authenticate 標頭,這裡會顯示失敗的詳細錯誤原因
options.IncludeErrorDetails = true; // 預設值為 true,有時會特別關閉 options.TokenValidationParameters = new TokenValidationParameters
{
// 透過這項宣告,就可以從 "sub" 取值並設定給 User.Identity.Name
NameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
// 透過這項宣告,就可以從 "roles" 取值,並可讓 [Authorize] 判斷角色
RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", // 一般我們都會驗證 Issuer
ValidateIssuer = true,
ValidIssuer = Configuration.GetValue<string>("JwtSettings:Issuer"), // 通常不太需要驗證 Audience
ValidateAudience = false,
//ValidAudience = "JwtAuthDemo", // 不驗證就不需要填寫 // 一般我們都會驗證 Token 的有效期間
ValidateLifetime = true, // 如果 Token 中包含 key 才需要驗證,一般都只有簽章而已
ValidateIssuerSigningKey = false, // "1234567890123456" 應該從 IConfiguration 取得
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration.GetValue<string>("JwtSettings:SignKey")))
};
});
services.AddSingleton<JwtHelpers>();
授权!!!顺序不可变
app.UseAuthentication();
app.UseAuthorization();
在appsetting中添加配置
"AllowedHosts": "*",
"JwtSettings": {
"Issuer": "JwtAuthDemo",
"SignKey": "1Zl4h9703IzROikK3@uK&&OEb"
},
最后在控制器使用
//注入
private readonly JwtHelpers jwt;
public MenuController JwtHelpers jwts)
{ jwt = jwts; }
案例:登录使用
[AllowAnonymous]
[HttpPost("~/signin")]
public IActionResult Login(string Email, string Pwd)
{ var list = dal.Login(Email, Pwd);
if (list.Success)
{
var token = jwt.GenerateToken(Email);
HttpContext.Response.Headers["token"] = token;
return Ok(list);
} return Ok(list); }
前台使用:vue方法
$http.interceptors.request.use(config=>{
const token=localStorage.getItem('token');
if(token){
config.headers.Authorization='Bearer'+token;
}
return config;
})
登录页面:
localStorage.setItem("token",res.headers.token);
最新文章
- 探索逻辑事务 TransactionScope
- VS 报cmath(19): error C2061: 语法错误: 标识符&ldquo;acosf&rdquo; 错误
- 【转】Android编程判断手机or平板
- 让时间处理简单化 【第三方扩展类库org.apache.commons.lang.time】
- Python学习笔记04
- win7下IE主页无法修改,IE设置无法保存解决方案
- URL详谈
- 【POJ】【1637】Sightseeing tour
- YTU 2607: A代码填空题--更换火车头
- org.apache.http.ProtocolException: Target host is not specified
- iframe和response.sendRedirect使用的问题
- USB系列之一:列出你的USB设备
- lightoj 1079 Just another Robbery
- 批量修改文件名java
- HDU-1754-I Hate It(线段树,简单,不过好像有点问题)
- MySQL服务相关
- details和summary可以对内容进行折叠
- WPF自学入门(九)WPF自定义窗口基类
- macOS 版微信小助手,支持微信多开、防撤回、远程控制mac、自动回复等等
- 机器学习 xgboost 笔记