Tar*_*rta 5 c# authentication refit
我刚刚在GitHub上找到了Refit库(链接:https : //github.com/reactiveui/refit)。除了在这个庞大世界中迈出的第一步之外,我还试图理解为什么当我们需要对例如API服务进行http调用时,为什么使用该库而不是通常的HttpClient会很方便。通过阅读,我了解了由我们自己创建,设置标头和其他配置的httpClient的原因太旧且太低级了。那就是改装的地方。然后,我尝试前进一步,并阅读有关身份验证的部分。我注意到,根据该库的github页面,为了使身份验证有效,我们需要再次处理HttpClient。我们终于设法摆脱了困境。官方页面上显示的示例是:
class AuthenticatedHttpClientHandler : HttpClientHandler
{
private readonly Func<Task<string>> getToken;
public AuthenticatedHttpClientHandler(Func<Task<string>> getToken)
{
if (getToken == null) throw new ArgumentNullException("getToken");
this.getToken = getToken;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// See if the request has an authorize header
var auth = request.Headers.Authorization;
if (auth != null)
{
var token = await getToken().ConfigureAwait(false);
request.Headers.Authorization = new AuthenticationHeaderValue(auth.Scheme, token);
}
return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
}
class LoginViewModel
{
AuthenticationContext context = new AuthenticationContext(...);
private async Task<string> GetToken()
{
// The AcquireTokenAsync call will prompt with a UI if necessary
// Or otherwise silently use a refresh token to return
// a valid access token
var token = await context.AcquireTokenAsync("http://my.service.uri/app", "clientId", new Uri("callback://complete"));
return token;
}
public async void LoginAndCallApi()
{
var api = RestService.For<IMyRestService>(new HttpClient(new AuthenticatedHttpClientHandler(GetToken)) { BaseAddress = new Uri("https://the.end.point/") });
var location = await api.GetLocationOfRebelBase();
}
}
Run Code Online (Sandbox Code Playgroud)
我想知道我在这里缺少什么概念。该库的目的是使用更多高级代码,设置足以调用API服务的接口。由于所有Http设置等都是在后台进行的,因此在身份验证之前可以实现此目的。但是,一旦进入该领域,我们就会再次发现HttpHandlers,HttpRequestMessages和HttpClients失去了库本身的作用。有人可以向我解释一下,我在大图中缺少什么吗?提前致谢
小智 4
我一直在尝试自己解决身份验证问题,以下是我自己在使用 Refit 时的观察结果。
TL;DR:有其他方法可以设置不需要使用 HttpClient 的身份验证,如下观察 2 和 3。
至少有三种方式来处理身份验证:
1) 如 GitHub 页面中所述,您可以传入带有 HttpClientHandler 的 HttpClient,并在处理程序中设置 Authorization 标头。就为什么需要使用处理程序而言,我注意到 Refit 会在发出 HTTP 请求之前将 Authorization 标头设置为属性中指定的任何值,如果您在创建 Refit 实例之前在 HttpClient 中设置标头不会工作,例如这不会工作:
[Get("/secretStuff")]
[Headers("Authorization: Bearer")]
Task<Location> GetLocationOfRebelBase();
. . .
var client = new HttpClient() { BaseAddress = new Uri("https://the.end.point/") };
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", someToken);
var api = RestService.For<IMyRestService>(client);
var location = await api.GetLocationOfRebelBase();
Run Code Online (Sandbox Code Playgroud)
授权标头将为“Authorization:Bearer”,令牌将不存在。您需要在发出 HTTP 请求之前在 HttpClientHandler(或 DelgatingHandler)中更改 HttpClient。
2) 创建 Refit api 客户端的新实例时,将基地址传递给 RestService.For 而不是 HttpClient 并指定 AuthorizationHeaderValueGetter,例如:
var gitHubApi = RestService.For<IGitHubApi>("https://api.github.com", new RefitSettings {
AuthorizationHeaderValueGetter = () => {
var token = SomeMethodToGetAToken();
Task.FromResult(token);
}
});
Run Code Online (Sandbox Code Playgroud)
3)将token传入api方法,例如:
[Get("/users/{user}")]
Task<User> GetUser(string user, [Header("Authorization")] string authorization);
Run Code Online (Sandbox Code Playgroud)
Refit GitHub 页面中提到了这一点: https: //github.com/reactiveui/refit#dynamic-headers。
| 归档时间: |
|
| 查看次数: |
1428 次 |
| 最近记录: |