发送用户 ID 和 access_token
Posted
技术标签:
【中文标题】发送用户 ID 和 access_token【英文标题】:Sending user Id along with access_token 【发布时间】:2019-02-13 06:29:21 【问题描述】:我正在使用 React 前端的 ASP.NET Core 2.1 应用程序中实现 Auth0。
一旦用户进行身份验证,我就会得到一个access_token
和一个id_token
。我很清楚access_token
的目的是授予对我的 API 方法的访问权限。我也知道id_token
提供了我可以在我的前端应用程序中使用的用户数据。
问题/担忧是关于在我进行 API 调用时将用户数据(例如 userId
)发送到我的后端。除了在我的 POST
请求的正文中包含 userId
之外,还有其他方法可以将其发送到我的 API 方法吗?
在 Auth0 之前,我使用了其他几个解决方案,我从他们那里收到的 JWT token
总是包括 userId
、username
等。我认为这是一种更安全的方法,因为即使人们可以看到是什么在JWT token
中,签名允许我们确保数据不被篡改。
尽管我的 API 调用是通过 SSL
保护的,但与通过 JWT token
发送它相比,我觉得在我的请求正文中包含进行 API 调用的人的 userId
不太安全。
我在这里遗漏了什么,还是我们确实通过 API 调用中的常规方式发送 userId
,即在 POST
调用的正文中或在 GET
调用的查询字符串中?
【问题讨论】:
从访问令牌中获取用户信息。您只需通过指定范围(例如openid profile
)来指定要从身份提供者那里获得的声明。然后,通常会在 api 项目中使用 User.Claims
访问声明。 sub
声明是用户 ID。
【参考方案1】:
好问题,我上周遇到了同样的问题,最后用同样的JWTAccessToken
解决了。
问题在于,在生成可以在服务器中检索的访问令牌时,将经过身份验证的用户的 UserId 添加为声明。
为访问令牌添加声明
首先将用户的 ID 添加到您的声明列表中。
List<Claim> claims = new List<Claim>();
claims.Add(new Claim("UserId", user.Id.ToString()));
然后生成访问令牌。
SecurityToken token = new JwtSecurityToken(
issuer: YOUR_ISSUER,
audience: YOUR_AUDIENCE,
claims: claims,
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddMinutes(60),
signingCredentials: credentials
);
假设您已经知道如何在生成最终令牌之前执行这些步骤,这些步骤是从您在上面的问题中显示的 oAuth
和 JWT
的能力中扣除的。
从访问令牌中检索声明
要从他们的 access_token 中读取 UserId,让我们创建几个帮助程序/扩展方法来帮助我们从控制器的 RequestContext
中读取 access_token。
public static string GetUserId(this ControllerBase controller)
string securityKey = "YOUR_SECURITY_KEY";
SymmetricSecurityKey key = new SymmetricSecurityKey(new UTF8Encoding().GetBytes(securityKey));
JwtSecurityTokenHandler token_handler = new JwtSecurityTokenHandler();
var tokenValidationParams = new TokenValidationParameters
ValidateAudience = false,
ValidateIssuer = false,
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateLifetime = false
;
string bearer = controller.HttpContext.Request.Headers["Authorization"].ToString().Replace("Bearer", string.Empty).Trim(' ');
List<Claim> claims = token_handler.ValidateToken(bearer, tokenValidationParams, out SecurityToken token).Claims.ToList();
Claim userClaim = claims.FirstOrDefault(x => x.Type == "UserId");
if(userClaim != null)
return userClaim.Value;
else
throw new Exception("Invalid AccessToken. UserId claim not found");
如何使用
现在让我们使用它在我们的任何控制器中获取 UserId:
[Authorize]
public class ExampleController : Controller
public IActionResult Index()
string userId = this.GetUserId();
// --> continuing code goes here.
【讨论】:
我实际上是在生成令牌的 Auth0 服务的上下文中说的。不过,我感谢您的回答并接受了它。话虽如此,在 Auth0 服务中可以通过“规则”向access_token
添加自定义声明。我能够在access_token
中包含用户 ID、名字、姓氏和用户的电子邮件地址。
Auth0 正在生成 access_token,因此您答案的第一部分是无关紧要的。至于答案的第二部分,JwtBearer 身份验证处理程序将为您完成所有这些工作,并且声明将在 ClaimsPrincipal HttpContext.User
上可用(在 ControllerBase.User
中引用)。 UserId
可以通过对var id = User.Claims.FirstOrDefault(x => x.Type == "userId");
的简单调用在控制器中访问。这不应该是一个公认的答案。以上是关于发送用户 ID 和 access_token的主要内容,如果未能解决你的问题,请参考以下文章
请问一下,C# js里面文本框的改变事件怎么写(主要是实现给用户发送信息,绑定2个文本框,一个存id)
F4 workerman 长连接绑定用户id实现一对一客服聊天