.NET Core如何全局獲取用戶信息?

前言

在增刪改查中的增和改操作中,我們經常需要更新數據流的創建人和修改人,無論我們項目是基於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接口而實現全局獲取用戶信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章