十年河東,十年河西,莫欺少年窮
學無止境,精益求精
NetCore獲取請求的完整/絕對路徑及相對路徑方法如下:
using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FranchiseeApi.Helper { public static class UrlHelper { /// <summary> /// 獲取絕對路徑 https://localhost:44351/V1/Teacher/GetTeacherList /// </summary> /// <param name="request"></param> /// <returns></returns> public static string GetAbsoluteUri(this HttpRequest request) { return new StringBuilder() .Append(request.Scheme) .Append("://") .Append(request.Host) .Append(request.PathBase) .Append(request.Path) .Append(request.QueryString) .ToString(); } /// <summary> /// 獲取接口相對路徑 /V1/Teacher/GetTeacherList /// </summary> /// <param name="request"></param> /// <returns></returns> public static string GetrelativeUri(this HttpRequest request) { return request.Path; } } }
還有一種獲取完整/絕對路徑方法如下:
string displayUrl = HttpContext.Request.GetDisplayUrl();
那么獲取這些地址有什么用呢?
如果我們開發一個NetCore.WebApi的項目,那么要想做到安全,除了Token驗證以外,還需要一套后端權限管理系統,即使有了后端權限管理系統,也不能做到【絕對】安全,這時候,我們就有必要對請求的接口做驗證,驗證當前請求用戶有沒有權限訪問該接口。
那么怎么做呢?
第一步:用戶登錄,返回用戶的Token及功能權限【菜單及按鈕權限】。
第二步:在用戶訪問有權限限制的接口前,通過在 父親基類 OnActionExecuting 方法中構造驗證方法,如下:
/// <summary> /// 第4步 執行OnActionExecuting方法 /// </summary> /// <param name="context"></param> public override void OnActionExecuting(ActionExecutingContext context) { //驗證Token是否正確 string displayUrl = HttpContext.Request.GetDisplayUrl(); if (displayUrl.Contains("Api/V1/Franchisee/Login")) { base.OnActionExecuting(context); } else { //解析Token 賦值給UserData if (!Request.Headers.TryGetValue("Authorization", out var apiKeyHeaderValues)) { CurrentUser = null; } else { //swagger 需要加Bearer 開頭 真實的Token中也不存在空格 因此 Replace 是為了兼容swagger var token = apiKeyHeaderValues.FirstOrDefault().Replace("Bearer ", ""); var jwtToken= new JwtSecurityTokenHandler().ReadJwtToken(token); var roleLst = jwtToken.Claims.Where(A => A.Type.Contains("role")).ToList(); if (roleLst != null) { foreach(var item in roleLst) { if (!string.IsNullOrEmpty(item.Value)) { CurrentUser.RoldeCodeList.Add(item.Value); } } } var NameModel = jwtToken.Claims.Where(A => A.Type.Contains("name")).ToList().FirstOrDefault(); CurrentUser.Account = NameModel == null ? "" : NameModel.Value; var userdataModel = jwtToken.Claims.Where(A => A.Type.Contains("userdata")).ToList().FirstOrDefault(); string UserDataJson = userdataModel == null ? "" : userdataModel.Value; var UserData = JsonConvert.DeserializeObject<TokenFranchiseeModel>(UserDataJson); CurrentUser.userData = UserData; var expModel = jwtToken.Claims.Where(A => A.Type.Contains("exp")).ToList().FirstOrDefault(); CurrentUser.exp = expModel == null ? "" : expModel.Value; } //獲取請求的相對路徑、 var relativeUri = UrlHelper.GetrelativeUri(HttpContext.Request); // //非登錄接口均需要進行接口訪問權限的驗證,我們將接口訪問權限存儲到數據庫中,這樣即使我們的Token別盜取,他也只能訪問盜取Token對應的接口權限。 //驗證接口權限 // //驗證接口權限待完善 // //驗證不通過,拋出異常,由異常中間件捕獲並返回異常消息。 // } }
關於NetCore Action的執行順序,可參考我的博客:Net Core 頁面的生命周期 + OnActionExecuting
@天才卧龍的博客