我有以下代碼來生成令牌。
如果令牌已經生成,我如何確保重新使用它。令牌用于后續 API 呼叫。
public interface ITokenClient
{
Task<string> GetToken();
}
public class TokenClient : ITokenClient
{
private static HttpClient httpClient = new HttpClient();
string _cachedToken;
DateTime _tokenRetrievalTime;
public async Task<string> GetToken()
{
if (string.IsNullOrEmpty(_cachedToken) || _tokenRetrievalTime.AddMinutes(55) > DateTime.Now)
{
_cachedToken = await GetTokenFromServer();
_tokenRetrievalTime = DateTime.Now;
return _cachedToken;
}
else
{
return _cachedToken;
}
}
async Task<string> GetTokenFromServer()
{
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("grant_type", "password"));
postData.Add(new KeyValuePair<string, string>("client_id", _clientId));
postData.Add(new KeyValuePair<string, string>("client_secret", _clientSecret));
HttpContent content = new FormUrlEncodedContent(postData);
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var client = _httpClientFactory.CreateClient();
var responseResult = await httpClient.PostAsync(_forgeUrl, content);
string token = await r.
responseResult.Content.ReadAsStringAsync();
return token;
}
}
并注冊為單身人士。
CastleClassFactory.Instance.Container.Register(Component.For<ITokenClient>()
.ImplementedBy<TokenClient>().Interceptors<LoggingInterceptor>().LifeStyle.Singleton);
uj5u.com熱心網友回復:
令牌的有效期為 1 小時。所以你只需要在獲得新令牌之前將其存盤 1 小時。理想情況下,您會在時間限制結束前幾分鐘獲得令牌,以減少使用無效令牌的機會。
因此,讓我們創建一個負責獲取和快取令牌的類。此類需要在您的依賴注入容器中注冊為單例,以便只有一個實體。否則你會一直不必要地獲得新的代幣。我不知道您使用的是什么依賴注入容器,因此您必須研究如何將我們的 TokenClient 類注冊為單例。
我們將在 DateTime 欄位中捕獲獲取令牌的時間,并在欄位中捕獲令牌本身。
public class TokenClient
{
readonly IHttpClientFactory _httpClientFactory;
string _cachedToken;
DateTime _tokenRetrievalTime;
public TokenClient(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<string> GetToken()
{
if (string.IsNullOrEmpty(_cachedToken) || _tokenRetrievalTime is null || _tokenRetrievalTime.AddMinutes(55) > DateTime.Now))
{
_cachedToken = await GetTokenFromServer();
_tokenRetrievalTime = DateTime.Now;
return _cachedToken;
}
else
{
return _cachedToken;
}
}
async Task<string> GetTokenFromServer()
{
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("grant_type", "password"));
postData.Add(new KeyValuePair<string, string>("client_id", _clientId));
postData.Add(new KeyValuePair<string, string>("client_secret", _clientSecret));
HttpContent content = new FormUrlEncodedContent(postData);
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var client = _httpClientFactory.CreateClient();
var responseResult = await client.PostAsync(_tokenUrl, content);
string token = await responseResult.Content.ReadAsStringAsync();
return token;
}
}
除了快取令牌之外,我在這里做了一些不同的事情。我正在使用 IHttpClientFactory 來獲取 HttpClient 的一個實體,以避免出現您使用 HttpClient 錯誤并且正在破壞您的軟體并且您可能仍在使用 HttpClient 錯誤并且正在破壞您的軟體中詳述的問題。更好的解決方案是使用Flurl,它會為您處理這些細節。
與您的代碼相比,我更改的另一件事是我正在正確等待回傳任務的呼叫。這可以防止代碼死鎖,并有助于保持高效運行。有關更多資訊,請參閱Async Await Best Practices和8 Await Async Mistakes You should avoid。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/346043.html
標籤:C# asp.net asp.net-mvc asp.net-web-api
上一篇:AJAX成功/錯誤功能不起作用
