.NET Core如何全局獲取用戶信息?
- 2021 年 7 月 6 日
- 筆記
- Asp.Net Core, ASP.NET CORE WebAPi
前言
在增刪改查中的增和改操作中,我們經常需要更新數據流的創建人和修改人,無論我們項目是基於DDD,抑或是簡單僅有服務層,此時我們都需要獲取用戶信息,那麼我們只能將用戶標識從控制器層層傳遞到服務或倉儲層?鑒於如上場景很常見,難道我們沒發覺這樣做很是繁瑣嗎?於是乎,我們想要解放生產力,下面咱們來聊聊我個人的想法
全局獲取用戶信息
既然是全局獲取用戶信息,難道是定義靜態變量?怎麼可能,當然是基於請求而獲取,基於靜態變量必然存在多個用戶請求覆蓋信息的情況,那我們到底應該怎麼全局獲取?首先我們想到的過濾器比如ActionFilter…等等,但要是我們需要進行異步操作呢?貌似又不可行,根據我查詢官方文檔,沒搞錯的話,應該是從1.0開始就給出了異步過濾器,那就是IAsyncActionFilter,此方法不同於ActionFilter的是,它能夠處理異步操作,同時它是在模型綁定完成之後執行,也就是只有一個異步方法
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { await next(); }
接下來我們定義全局用戶會話類,如下:
public class Session { /// <summary> /// 用戶id /// </summary> public string UserId { get; set; } /// <summary> /// 用戶名 /// </summary> public string UserName { get; set; } }
緊接着,比如項目我們使用JWT,則拿到聲明中用戶標識和用戶賬號,那麼我們接下來我們只需要實現上述異步action過濾器接口即可,如下:
public class AsyncSessionFilter : IAsyncActionFilter { private readonly Session _session; public AsyncSessionFilter(Session session) { _session = session; } public async Task OnActionExecutionAsync( ActionExecutingContext context, ActionExecutionDelegate next) { var user = context.HttpContext.User; _session.UserId = user.FindFirst(JwtRegisteredClaimNames.Sub)?.Value; _session.UserName = user.FindFirst(JwtRegisteredClaimNames.UniqueName)?.Value; await next(); } }
最後,則很簡單的進行上述接口實現和會話注入,如下:
//註冊用戶會話 services.AddScoped<Session>(); //註冊全局過濾器 services.AddControllers(options => { options.Filters.Add<AsyncSessionFilter>(); })
在實際使用中,我們只需要在倉儲或服務層構造函數使用Session,即可拿到用戶名和用戶id,從而最終解決對於新增和更改操作處理操作人信息
總結
在.NET Core中藉助實現異步IAsyncActionFilter接口而實現全局獲取用戶信息