文章目錄
Swagger
什麼是Swagger
Swagger 是一個規範和完整的框架,用於生成、描述、調用和可視化 RESTful 風格的 Web 服務。方便前後端接口對接。
NuGet安裝
打開NuGet程序包,搜索“Swashbuckle.AspNetCore”安裝。
注意:NETCore3.0版本需要使用Swashbuckle.AspNetCore5.0以上的版本。我這個用的是NETCore2.2。
Startup註冊Swagger
在Startup的ConfigureServices方法中註冊Swagger服務。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
#region Swagger
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v0.1.0",//版本號
Title = "ZZTApi文檔",//文檔標題
Description = "框架說明文檔",//文檔描述
TermsOfService = "None",//服務條款
Contact = new Contact { Name = "zzt", Email = "[email protected]", Url = "www.baidu.com" }//聯繫人
});
});
#endregion
}
在Startup的Configure方法裏面調用Swagger服務
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
#region Swagger
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
});
#endregion
}
保存後按F5調試,瀏覽器地址訪問http://localhost:51146/swagger/index.html(每個人端口號可能不一樣)。
設置默認首頁打開Swagger
如果不想每次訪問都要輸入/swagger/index.html來使用Swagger,希望根目錄就是Swagger界面。可以這樣設置:
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
c.RoutePrefix = "";//路徑配置,設置爲空,表示直接訪問該文件。
});
有可能每次運行都會默認訪問http://localhost:51146/api/values這個路徑下的地址。需要在launchSettings.json文件下修改。
爲接口添加註釋
如圖,文檔裏面我們需要在紅框裏面爲接口添加註釋,以方便理解每個接口的功能。
右鍵項目名稱=>屬性=>生成,勾選“輸出”下面的“xml文檔文件”,系統會默認生成一個,你也可以自定義。
這裏我用的是相對路徑。添加取消警告代碼1590。否則會有一些警告。
在接口方法上邊添加註釋,說明每個接口的功能。
最後在services.AddSwaggerGen裏面添加XML文檔的路徑。
#region Swagger
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v0.1.0",
Title = "ZZTApi文檔",
Description = "框架說明文檔",
TermsOfService = "None",
Contact = new Contact { Name = "zzt", Email = "[email protected]", Url = "www.baidu.com" }
});
#region 爲 Swagger JSON and UI設置xml文檔註釋路徑
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);//獲取應用程序所在目錄(絕對,不受工作目錄影響,建議採用此方法獲取路徑)
var xmlAPIPath = Path.Combine(basePath, "ZZTCoreAPI.xml");//這個就是剛剛配置的xml文件名
var xmlModelPath = Path.Combine(basePath, "ZZTCoreModel.xml");//這個是引用model層的XML文檔。設置輸出XML文檔的方法跟上面的一樣。
c.IncludeXmlComments(xmlAPIPath, true);//第二個參數true表示用控制器的XML註釋。默認是false
c.IncludeXmlComments(xmlModelPath, true);
#endregion
});
以上代碼還添加了一個model層的XML文檔。設置方法是一樣的。它的效果可以看以下幾張圖。
以上就是Swagger一些簡單應用
JWT
什麼是JWT
JWT,即JSON Web Tokens,是一種基於JSON的、用於在網絡上聲明某種主張的令牌(token)。JWT通常由三部分組成: 頭信息(header), 消息體(payload)和簽名(signature)。它是一種用於雙方之間傳遞安全信息的表述性聲明規範。JWT作爲一個開放的標準(RFC 7519),定義了一種簡潔的、自包含的方法,從而使通信雙方實現以JSON對象的形式安全的傳遞信息。
註冊授權認證服務
在Startup的ConfigureServices方法裏面添加以下代碼
#region JWT
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Audience:Secret"]));
services.AddAuthentication("Bearer").AddJwtBearer(o=> {
o.TokenValidationParameters = new TokenValidationParameters
{
//是否開啓密鑰認證和key值
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
//是否開啓發行人認證和發行人
ValidateIssuer = true,
ValidIssuer = Configuration["Audience:Issuer"],
//是否開啓訂閱人認證和訂閱人
ValidateAudience = true,
ValidAudience = Configuration["Audience:Audience"],
//認證時間的偏移量
ClockSkew = TimeSpan.Zero,
//是否開啓時間認證
ValidateLifetime = true,
//是否該令牌必須帶有過期時間
RequireExpirationTime = true
};
});
#endregion
其中Configuration[“Audience:xxx”]是讀取appsettings.json配置文件裏面的一些參數,參數如下:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"Audience": {
"Secret": "sdfsdfsrty45634kkhllghtdgdfss345t678fs",
"Issuer": "ZZT",
"Audience": "Nobody"
}
}
註冊後需要在Configure
方法裏面加入代碼app.UseAuthentication();
來開啓服務
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
//HTTP管道是有先後順序的,一定要寫在 app.Mvc() 之前,否則不起作用。
app.UseAuthentication();
app.UseMvc();
#region Swagger
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
c.RoutePrefix = "";//路徑配置,設置爲空,表示直接訪問該文件,
});
#endregion
}
API接口添加授權策略
在接口方法上邊加入Authorize
特性,表示該接口需要進行授權認證。
帶上Roles參數表示是基於角色的策略
如果有多個角色授權的話,在Startup的ConfigureServices方法中加入以下代碼
// 【授權】,好處就是不用在controller中,寫多個 roles 。
// 然後接口授權這麼寫 [Authorize(Policy = "Admin")]
services.AddAuthorization(options =>
{
options.AddPolicy("Client", policy => policy.RequireRole("Client").Build());
options.AddPolicy("Admin", policy => policy.RequireRole("Admin").Build());
options.AddPolicy("SystemOrAdmin", policy => policy.RequireRole("Admin", "System"));
});
獲取JWT的Token
以下代碼是獲取JWTToken的方法,作用是傳入一個model,生成Token,這個model可以根據需求自己定義,涉及主要的兩個對象JwtSecurityToken
和JwtSecurityTokenHandler
。
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace ZZTCoreAPI.Common
{
public class JwtHelper
{
public static string IssueJWT(TokenModelJWT tokenModel)
{
var dateTime = DateTime.UtcNow;
string iss = Appsettings.GetConfigure("Audience:Issuer");
string aud = Appsettings.GetConfigure("Audience:Audience");
string secret = Appsettings.GetConfigure("Audience:Secret");
//var claims = new Claim[] //old
var claims = new List<Claim>
{
//下邊爲Claim的默認配置
new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Uid.ToString()),
new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
new Claim(JwtRegisteredClaimNames.Nbf,$"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
//這個就是過期時間,目前是過期100秒,可自定義,注意JWT有自己的緩衝過期時間
new Claim (JwtRegisteredClaimNames.Exp,$"{new DateTimeOffset(DateTime.Now.AddSeconds(100)).ToUnixTimeSeconds()}"),
new Claim(JwtRegisteredClaimNames.Iss,iss),
new Claim(JwtRegisteredClaimNames.Aud,aud),
//new Claim(ClaimTypes.Role,tokenModel.Role),//爲了解決一個用戶多個角色(比如:Admin,System),用下邊的方法
};
// 可以將一個用戶的多個角色全部賦予;
// 作者:DX 提供技術支持;
claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));
//祕鑰 (SymmetricSecurityKey 對安全性的要求,密鑰的長度太短會報出異常)
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var jwt = new JwtSecurityToken(
issuer: iss,
claims: claims,
signingCredentials: creds);
var jwtHandler = new JwtSecurityTokenHandler();
var encodedJwt = jwtHandler.WriteToken(jwt);
return encodedJwt;
}
}
/// <summary>
/// 令牌
/// </summary>
public class TokenModelJWT
{
/// <summary>
/// Id
/// </summary>
public long Uid { get; set; }
/// <summary>
/// 角色
/// </summary>
public string Role { get; set; }
/// <summary>
/// 職能
/// </summary>
public string Work { get; set; }
}
}
以下代碼是獲取Token的接口,作用是根據傳入的賬號密碼生成一個model傳入以下代碼中的IssueJWT
方法以獲取Token返回給前端。前端在 Http 的 Header 裏,增加屬性Authorization,並把這個Token帶上Bearer 即Bearer {Token}
這個值賦給Authorization屬性作爲訪問其他接口的授權校驗。爲什麼一定要加Bearer?這是規定。
[HttpGet]
public ActionResult<string> GetToken(string name, string pwd)
{
string jwtStr = string.Empty;
bool suc = false;
//這裏就是用戶登陸以後,通過數據庫去調取數據,分配權限的操作
//這裏直接寫死了
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(pwd))
{
return new JsonResult(new
{
Status = false,
message = "用戶名或密碼不能爲空"
});
}
TokenModelJWT tokenModel = new TokenModelJWT();
tokenModel.Uid = 1;
tokenModel.Role = name;
jwtStr = JwtHelper.IssueJWT(tokenModel);
suc = true;
return Ok(new
{
success = suc,
token = jwtStr
});
}
以上就是JWT的應用。
Swagger中開啓JWT服務
我們要測試 JWT 授權認證,就必定要輸入 Token令牌。Swagger 已經幫我們實現了這個錄入 Token令牌的功能,需要在服務中開啓:
在ConfigureServices -> AddSwaggerGen 服務中,增加以下代碼,注意是swagger服務內部:
#region Token綁定到ConfigureServices
//添加header驗證信息
//c.OperationFilter<SwaggerHeader>();
var security = new Dictionary<string, IEnumerable<string>> { { "ZZTAPI", new string[] { } }, };
c.AddSecurityRequirement(security);
//方案名稱“Blog.Core”可自定義,上下一致即可
c.AddSecurityDefinition("ZZTAPI", new ApiKeyScheme
{
Description = "JWT授權(數據將在請求頭中進行傳輸) 直接在下框中輸入Bearer {token}(注意兩者之間是一個空格)\"",
Name = "Authorization",//jwt默認的參數名稱
In = "header",//jwt默認存放Authorization信息的位置(請求頭中)
Type = "apiKey"
});
#endregion
測試流程
F5進入調試,進入Swagger界面,調用剛剛寫的GetToken接口獲取Token
將Token複製填到Authorize屬性
最後訪問我們之前加了[Authorize(Roles ="zzt")]
特性的接口
可以看到是訪問得到的,如果我們不帶Token去訪問的話會返回401的狀態碼,請求要求身份驗證。
完!
參考文章:https://www.cnblogs.com/laozhang-is-phi/p/9511869.html#autoid-2-0-0