问题
I'm implementing Auth0 in my ASP.NET Core 2.1 app with React front-end.
Once the user authenticates, I get both an access_token
and an id_token
. I'm clear that the purpose of access_token
is to grant access to my API methods. I also understand that the id_token
provides user data which I can use in my front-end app.
The question/concern is about sending user data, such as userId
to my backend when I make API calls. Other than including userId
in the body of my POST
request, is there another way to send it to my API method?
Prior to Auth0, I used a couple of other solutions and the JWT token
I received from them always included userId
, username
, etc. I thought this was a more secure approach because even though one can see what's in a JWT token
, the signature allows us to make sure the data is not temperered with.
Even though my API calls are secured through SSL
, I feel including the userId
of the person who's making the API call in the body of my request is less secure compared to sending it through a JWT token
.
Am I missing something here or do we indeed send the userId
through the regular means in an API call i.e. in the body of a POST
call or in the query string of a GET
call?
回答1:
Good question man, i was going through the same problem last week and finally figured it out using the same JWTAccessToken
.
The catch is in adding the UserId of the authenticated user as a claim when generating an access token which you can retrieve in the server.
Adding Claims To Access Token
Add the user's id to your list of claims first.
List<Claim> claims = new List<Claim>();
claims.Add(new Claim("UserId", user.Id.ToString()));
Then generate an access token.
SecurityToken token = new JwtSecurityToken(
issuer: {YOUR_ISSUER},
audience: {YOUR_AUDIENCE},
claims: claims,
notBefore: DateTime.UtcNow,
expires: DateTime.UtcNow.AddMinutes(60),
signingCredentials: credentials
);
Am assuming you already know how to perform the steps before reaching this final token generation as deducted from your prowess of oAuth
and JWT
shown above in your question.
Retrieve Claim From Access Token
To read a UserId from their access_token, let's create a couple of helper/extension methods to help us in reading an access_token from the RequestContext
of a controller.
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");
}
}
How To Use
Let's now use this to get the UserId in any of our controllers:
[Authorize]
public class ExampleController : Controller
{
public IActionResult Index()
{
string userId = this.GetUserId();
// --> continuing code goes here.
}
}
来源:https://stackoverflow.com/questions/52230383/sending-user-id-along-with-access-token