.NET Core如何全局獲取用戶信息?
鑒于如上場景很常見,難道我們沒發覺這樣做很是繁瑣嗎?于是乎,我們想要解放生產力,下面咱們來聊聊我個人的想法。
全局獲取用戶信息
既然是全局獲取用戶信息,難道是定義靜態變量?怎么可能,當然是基于請求而獲取,基于靜態變量必然存在多個用戶請求覆蓋信息的情況。
那我們到底應該怎么全局獲取?首先我們想到的過濾器比如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接口而實現全局獲取用戶信息