Get userId from JWT on all Controller methods?
Firstly I create IUserProvider
interface with IHttpContextAccessor
injection to make mocks for these interfaces in unit tests.
public interface IUserProvider
{
string GetUserId();
}
Than implementation is
public class UserProvider : IUserProvider
{
private readonly IHttpContextAccessor _context;
public UserProvider (IHttpContextAccessor context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}
public string GetUserId()
{
return _context.HttpContext.User.Claims
.First(i => i.Type == ClaimTypes.NameIdentifier).Value;
}
}
So you can use interface IUserProvider
in your controller without inheritance
[Authorize]
[ApiController]
public class MyController : ControllerBase
{
private readonly IUserProvider _userProvider;
public MyController(IUserProvider userProvider)
{
_userProvider = userProvider ?? throw new ArgumentNullException(nameof(userProvider ));
}
[HttpGet]
[Route("api/My/Something")]
public async Task<ActionResult> GetSomething()
{
try
{
var userId= _userProvider.GetUserId();
}
}
}
ControllerBase
contains User
property that is type of ClaimsPrincipal
You can access user claims by User.Claims
and no need for IPrincipal
Create a base controller which contains GetUserId
method as protected
public abstract class BaseController : Controller
{
protected int GetUserId()
{
return int.Parse(this.User.Claims.First(i => i.Type == "UserId").Value);
}
}
And all controllers inherit form this, now all controllers can access UserId