重用令牌 asp.net web api c#

reuse token asp.net web api c#

我有以下代码来生成令牌。

如果令牌已经生成,我如何才能确保重新使用它。该令牌用于后续 API 调用。

 using (var client = new HttpClient())
{
    var postData = new List<KeyValuePair<string, string>>();
    postData.Add(new KeyValuePair<string, string>("username", _user));
    postData.Add(new KeyValuePair<string, string>("password", _pwd));
    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 responseResult = client.PostAsync(_tokenUrl, content).Result;

    return responseResult.Content.ReadAsStringAsync().Result;
}

令牌有效期为1小时。所以你只需要在获得新令牌之前将其存储 1 小时。理想情况下,您会在时间限制结束前几分钟获得一个令牌,以减少您使用无效令牌的机会。

那么,让我们创建一个 class 负责获取和缓存令牌。此 class 需要作为单例注册到您的依赖注入容器中,以便只有一个实例。否则你会一直不必要地获得新的代币。我不知道你使用的是什么依赖注入容器,所以你必须研究如何将我们的 TokenClient class 注册为单例。

我们将在 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.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 的实例,以避免 You're Using HttpClient Wrong And It's Destablizing Your Software and You're probably still using HttpClient Wrong And It's Destabilizing Your Software. An even better solution would be to use Flurl 中详述的问题,它会为您处理这些细节。

与您的代码相比,我更改的另一件事是我正在正确等待 return 任务的调用。这可以防止代码死锁并有助于保持 运行 高效。有关详细信息,请参阅 Async Await Best Practices and 8 Await Async Mistakes You Should Avoid