Cra*_*aig 8 .net c# jwt asp.net-core
我正在创建一个使用JWT进行身份验证和授权的Core 2.0 Web API项目.我想要保护的控制器方法都使用Authorize属性进行修饰.
这很有效.如果我在Bearer标题中传递JWT,我得到200.如果我没有通过JWT,我得到401.所有工作.在我的JWT中,我在授权时将用户ID存储在'UserId'字段中.
var claimsdata = new[] {
new Claim("UserId", user.Id.ToString()),
Run Code Online (Sandbox Code Playgroud)
然后我有一个扩展方法:
public static string GetUserId(this IPrincipal user)
{
if (user == null)
return string.Empty;
var identity = (ClaimsIdentity)user.Identity;
IEnumerable<Claim> claims = identity.Claims;
return claims.FirstOrDefault(s => s.Type == "UserId")?.Value;
}
Run Code Online (Sandbox Code Playgroud)
在我的控制器方法中,使用'Authorize',我经常需要用户的ID.所以我调用了我的GetUserId方法.这有效.但是,我不确定这是否是从令牌获取Id的最佳方式.
int.TryParse(User.GetUserId(), out _userId);
Run Code Online (Sandbox Code Playgroud)
我需要在所有控制器上使用该代码.我不能在构造函数中做到这一点,因为我认为这是错误的.
我在这做对了吗?
Hes*_*ehr 12
ControllerBase包含User属性类型的属性ClaimsPrincipal
您可以通过User.Claims而无需访问用户声明IPrincipal
创建一个包含GetUserId方法的基本控制器protected
public abstract class BaseController : Controller
{
protected int GetUserId()
{
return int.Parse(this.User.Claims.First(i => i.Type == "UserId").Value);
}
}
Run Code Online (Sandbox Code Playgroud)
并且所有控制器都继承此形式,现在所有控制器都可以访问 UserId
小智 10
首先,我创建了IUserProvider带有IHttpContextAccessor注入的接口,以便在单元测试中为这些接口进行模拟。
public interface IUserProvider
{
string GetUserId();
}
Run Code Online (Sandbox Code Playgroud)
比实施是
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;
}
}
Run Code Online (Sandbox Code Playgroud)
所以你可以IUserProvider在你的控制器中使用接口而无需继承
[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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
你也可以使用
扩展方法
像这样
public static long GetUserID(this ClaimsPrincipal User)
{
return long.Parse(User.Claims.First(i => i.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").Value);
}
Run Code Online (Sandbox Code Playgroud)
并像这样在您的控制器中实现
[HttpDelete("DeleteAddress")]
public async Task<IActionResult> DeleteAddress([FromQuery] long AddressID)
{
try
{
long userID = this.User.GetUserID();
await _addressService.Delete(userID, AddressID);
return Ok();
}
catch (Exception err)
{
return Conflict(err.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
我希望它会帮助你
| 归档时间: |
|
| 查看次数: |
4781 次 |
| 最近记录: |