Sending user Id along with access_token

2019-08-21 04:00发布

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条回答
唯我独甜
2楼-- · 2019-08-21 04:55

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.
    }
}
查看更多
登录 后发表回答