1 回答

TA貢獻1828條經驗 獲得超3個贊
有兩種類型的身份驗證,cookie 和持有者。
如果 Cookie 使您保持登錄狀態,則持有者令牌無法登錄。因為持有者令牌設置為在某個時刻過期,不允許更改生存期。
訪問令牌過期后訪問資源 (api) 的唯一方法是讓用戶再次登錄或使用刷新令牌請求新的訪問令牌,而無需用戶交互。
您已經配置了它:
options.Scope.Add("offline_access");
每次登錄時,請求將至少包含一個刷新令牌。將其存放在安全的地方,并在需要時使用。默認情況下,它設置為僅一次使用。
您可以使用類似此代碼的內容來續訂令牌(因為您實際上不是在刷新它,而是在替換它)。需要包含“標識模型”NuGet 包,如標識服務器的示例所示。
private async Task<TokenResponse> RenewTokensAsync()
{
// Initialize the token endpoint:
var client = _httpClientFactory.CreateClient();
var disco = await client.GetDiscoveryDocumentAsync("http://localhost:5000");
if (disco.IsError) throw new Exception(disco.Error);
// Read the stored refresh token:
var rt = await HttpContext.GetTokenAsync("refresh_token");
var tokenClient = _httpClientFactory.CreateClient();
// Request a new access token:
var tokenResult = await tokenClient.RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = disco.TokenEndpoint,
ClientId = "mvc",
ClientSecret = "secret",
RefreshToken = rt
});
if (!tokenResult.IsError)
{
var old_id_token = await HttpContext.GetTokenAsync("id_token");
var new_access_token = tokenResult.AccessToken;
var new_refresh_token = tokenResult.RefreshToken;
var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);
// Save the information in the cookie
var info = await HttpContext.AuthenticateAsync("Cookies");
info.Properties.UpdateTokenValue("refresh_token", new_refresh_token);
info.Properties.UpdateTokenValue("access_token", new_access_token);
info.Properties.UpdateTokenValue("expires_at", expiresAt.ToString("o", CultureInfo.InvariantCulture));
await HttpContext.SignInAsync("Cookies", info.Principal, info.Properties);
return tokenResult;
}
return null;
}
默認情況下,刷新令牌用法配置為一次性使用。請注意,當存儲新的刷新令牌失敗并且你應該丟失它時,請求新的刷新令牌的唯一方法是強制用戶再次登錄。
另請注意,刷新令牌可能會過期。
退后一步,當訪問令牌過期或即將過期時,需要使用它:
var accessToken = await HttpContext.GetTokenAsync("access_token");
var tokenHandler = new JwtSecurityTokenHandler();
var jwtSecurityToken = tokenHandler.ReadJwtToken(accessToken);
// Depending on the lifetime of the access token.
// This is just an example. An access token may be valid
// for less than one minute.
if (jwtSecurityToken.ValidTo < DateTime.UtcNow.AddMinutes(5))
{
var responseToken = await RenewTokensAsync();
if (responseToken == null)
{
throw new Exception("Error");
}
accessToken = responseToken.AccessToken;
}
// Proceed, accessToken contains a valid token.
- 1 回答
- 0 關注
- 82 瀏覽
添加回答
舉報