How to implement JWT Refresh Tokens in asp.net core web api (no 3rd party)?

前端 未结 1 918
抹茶落季
抹茶落季 2021-02-01 19:56

I\'m in the process of implementing a web api using asp.net core that is using JWT. I am not using a third party solution such as IdentityServer4 as I am trying to learn.

<
相关标签:
1条回答
  • 2021-02-01 20:23

    First of all, you need to generate a refresh token and persist it somewhere. This is because you want to be able to invalidate it if needed. If you were to follow the same pattern as an access token - where all the data is contained within the token - a token that ends up in the wrong hands can the be used to generate new access tokens for the lifetime of the refresh token, which can be a really long time.

    So what the heck do you need to persist?

    You need a unique identifier of some sort that's not easy guessable, a GUID will do just fine. You also need the data to be able to issue a new access token, most likely a username. Having a username you can then skip the VerifyHashedPassword(...)-part but for the rest of it, just follow the same logic.

    To obtain a refresh token, you normally use the scope "offline_access", this being something that you provide in your model (CredentialViewModel) when making a token request. Unlike a normal access token request, you don't need to provide your username and password, but instead the refresh token. When getting a request with a refresh token, you lookup the persisted identifier and issue a token for the user found.

    Following is pseudo code for the happy path:

    [Route("Token")]
    [HttpPost]
    public async Task<IActionResult> CreateToken([FromBody] CredentialViewModel model)
    {
        if (model.GrantType is "refresh_token")
        {
            // Lookup which user is tied to model.RefreshToken
            // Generate access token from the username (no password check required)
            // Return the token (access + expiration)
        }
        else if (model.GrantType is "password")
        {
            if (model.Scopes contains "offline_access")
            {
                // Generate access token
                // Generate refresh token (random GUID + model.username)
                // Persist refresh token
                // Return the complete token (access + refresh + expiration)
            }
            else
            {
                // Generate access token
                // Return the token (access + expiration)
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题