ASP.NET Core 6 MVC 在 Service 層中取得 UserName

在使用身分驗證時,我們可以在 Controller 中直接使用 User.Identity.Name 取得使用者名稱,但是在 Service 中不能夠直接這樣做。在 Service 層中取得當前登入使用者最簡單的方式就是注入 IHttpContextAccessor ,就可以用同樣的方式取得,不過這樣 Service 層中會取得過多不需要的內容,並且也不太容易使用。本篇示範封裝一個 UserContextService,專門用來取得 UserId 和 UserName

建立 UserContextService

其實 UserContextService 很簡單,就只是把 IHttpContextAccessor 多包一層:
    
public class UserContextService
{
    private readonly IHttpContextAccessor _contextAccessor;

    public UserContextService(IHttpContextAccessor contextAccessor)
    {
        this._contextAccessor = contextAccessor;
    }

    /// <summary>
    /// 取得當前登入的使用者 Id
    /// </summary>
    public string? GetCurrentSessionUserId()
    {
        return _contextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier);
    }


    /// <summary>
    /// 取得當前登入的使用者名稱
    /// </summary>
    public string? GetCurrentSessionUserName()
    {
        return _contextAccessor.HttpContext?.User.Identity?.Name;
    }
}
    

注入服務:
    
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<UserContextService>();

var app = builder.Build();
    

註: 一定要加入 AddHttpContextAccessor ,不然會拋出例外

使用示範

建立測試 Service:
    
public class TestService
{
    private readonly ILogger<TestService> _logger;
    private readonly IUserResolveService _userResolveService;

    public TestService(ILogger<TestService> logger, IUserResolveService userResolveService)
    {
        _logger = logger;
        _userResolveService = userResolveService;
    }

    public string GetUserData()
    {
        
        var userId = _userResolveService.GetCurrentSessionUserId();
        var userName = _userResolveService.GetCurrentSessionUserName();
        _logger.LogInformation($"userId: {userId}, userName: {userName}");
        return userName;
    }
}
    

注入測試 Service:
    
builder.Services.AddScoped<TestService>();
    

建立測試 API:
    
public class TestController : ControllerBase
{
    private readonly TestService _testService;

    public TestController(TestService testService)
    {
        _testService = testService;
    }

    [HttpGet("/test")]
    public IActionResult Get()
    {
        return Ok(_testService.GetUserData());
    }
}
    

呼叫 /test 時會顯示 UserId 和 UserName ,範例輸出:
    
userId: 8888ff00-eeee-4321-8888-111111111111, userName: ruyut
    

留言