2017-04-18 30 views
8

Tôi đang trong quá trình triển khai api trên web bằng cách sử dụng lõi asp.net đang sử dụng JWT. Tôi không sử dụng giải pháp của bên thứ ba như IdentityServer4 như tôi đang cố gắng tìm hiểu.Làm cách nào để triển khai JWT Refresh Tokens trong api core asp.net core (không có bên thứ 3)?

Tôi đã nhận cấu hình JWT để hoạt động, nhưng tôi đã bị vướng vào cách triển khai mã thông báo làm mới khi thời gian JWT hết hạn.

Dưới đây là một số mã mẫu trong phương thức Cấu hình của tôi bên trong startup.cs.

app.UseJwtBearerAuthentication(new JwtBearerOptions() 
{ 
    AuthenticationScheme = "Jwt", 
    AutomaticAuthenticate = true, 
    AutomaticChallenge = true, 
    TokenValidationParameters = new TokenValidationParameters() 
    { 
     ValidAudience = Configuration["Tokens:Audience"], 
     ValidIssuer = Configuration["Tokens:Issuer"], 
     ValidateIssuerSigningKey = true, 
     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])), 
     ValidateLifetime = true, 
     ClockSkew = TimeSpan.Zero 
    } 
}); 

Dưới đây là phương pháp Bộ điều khiển được sử dụng để tạo JWT. Tôi đã đặt hết hạn 30 giây cho mục đích thử nghiệm.

[Route("Token")] 
    [HttpPost] 
    public async Task<IActionResult> CreateToken([FromBody] CredentialViewModel model) 
    { 
     try 
     { 
      var user = await _userManager.FindByNameAsync(model.Username); 

      if (user != null) 
      { 
       if (_hasher.VerifyHashedPassword(user, user.PasswordHash, model.Password) == PasswordVerificationResult.Success) 
       { 
        var userClaims = await _userManager.GetClaimsAsync(user); 

        var claims = new[] 
        { 
         new Claim(JwtRegisteredClaimNames.Sub, user.UserName), 
         new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) 
        }.Union(userClaims); 

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwt.Key)); 
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); 

        var token = new JwtSecurityToken(
          issuer: _jwt.Issuer, 
          audience: _jwt.Audience, 
          claims: claims, 
          expires: DateTime.UtcNow.AddSeconds(30), 
          signingCredentials: creds 
         ); 

        return Ok(new 
        { 
         access_token = new JwtSecurityTokenHandler().WriteToken(token), 
         expiration = token.ValidTo 
        }); 
       } 
      } 
     } 
     catch (Exception) 
     { 

     } 

     return BadRequest("Failed to generate token."); 
    } 

Sẽ rất biết ơn vì một số hướng dẫn.

+0

Mã bạn đăng là chỉ liên quan đến chứng thực thẻ truy cập, không làm mới thẻ. Bạn có thể chia sẻ mã nơi bạn tạo mã thông báo truy cập không? – naslund

+0

Chắc chắn, tôi đã thêm mã được sử dụng để tạo các JWT. – DJDJ

Trả lời

7

Trước hết, bạn cần phải tạo mã thông báo làm mới và tiếp tục tồn tại ở đâu đó. Điều này là do bạn muốn có thể làm mất hiệu lực nếu cần. Nếu bạn theo dõi cùng một mẫu như mã thông báo truy cập - nơi tất cả dữ liệu được chứa trong mã thông báo - mã thông báo kết thúc bằng tay sai có thể được sử dụng để tạo mã thông báo truy cập mới cho thời gian tồn tại của mã thông báo làm mới, có thể là một thời gian thực sự dài.

Vì vậy, bạn cần phải duy trì những gì? Bạn cần một số nhận dạng duy nhất của một số loại không dễ đoán, GUID sẽ hoạt động tốt. Bạn cũng cần dữ liệu để có thể phát hành mã thông báo truy cập mới, rất có thể là tên người dùng. Có một tên người dùng, bạn có thể bỏ qua phần VerifyHashedPassword (...) - nhưng phần còn lại của nó, chỉ cần làm theo cùng một logic.

Để nhận mã thông báo làm mới, bạn thường sử dụng phạm vi "offline_access", đây là thứ mà bạn cung cấp trong mô hình của mình (CredentialViewModel) khi thực hiện yêu cầu mã thông báo. Không giống như yêu cầu mã thông báo truy cập bình thường, bây giờ bạn không cần phải cung cấp tên người dùng và mật khẩu của mình, mà thay vào đó là mã thông báo làm mới. Khi nhận được yêu cầu có mã thông báo làm mới, bạn tra cứu số nhận dạng liên tục và phát hành mã thông báo cho người dùng được tìm thấy.

Sau đây là mã giả cho con đường hạnh phúc:

[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

Cảm ơn bạn đã nhập! – DJDJ

Các vấn đề liên quan