我刚刚解决了在gRPC拦截器中设置承载令牌所需的一些WASM异步代码,您可以像这样完成:
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
var call = continuation(request, context);
return new AsyncUnaryCall<TResponse>(
call.ResponseAsync,
GetMetadata(),
call.GetStatus,
call.GetTrailers,
call.Dispose);
}
private async Task<Metadata> GetMetadata()
{
try
{
if (!string.IsNullOrEmpty(await _authenticationManager.TryRefreshToken()))
_snackbar.Add("Refreshed Token.", Severity.Success);
var token = _authenticationManager.Token;
var metadata = new Metadata();
if (!string.IsNullOrEmpty(token))
{
metadata.Add("Authorization", $"Bearer {token}");
var userIdentity = (await _authenticationStateProvider.GetAuthenticationStateAsync()).User.Identity;
if (userIdentity!.IsAuthenticated)
metadata.Add("User", userIdentity.Name!);
}
else
{
_authenticationManager.Logout().GetAwaiter().GetResult();
_navigationManager.NavigateTo("/");
}
return metadata;
}
catch (Exception ex)
{
throw new InvalidOperationException("Failed to add token to request metadata", ex);
}
}
编辑:由于某些原因,尽管此异步代码运行了,但它实际上并没有将标头设置到请求中,所以您必须执行以下黑客操作:
public class AuthenticationInterceptor : Interceptor
{
private readonly IAuthenticationManager _authenticationManager;
private readonly ISnackbar _snackbar;
private readonly NavigationManager _navigationManager;
private readonly AuthenticationStateProvider _authenticationStateProvider;
private Metadata? _metadata;
public AuthenticationInterceptor(
IAuthenticationManager authenticationManager,
ISnackbar snackbar,
NavigationManager navigationManager,
AuthenticationStateProvider authenticationStateProvider)
{
_authenticationManager = authenticationManager;
_snackbar = snackbar;
_navigationManager = navigationManager;
_authenticationStateProvider = authenticationStateProvider;
}
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
TRequest request,
ClientInterceptorContext<TRequest, TResponse> context,
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
{
_ = new AsyncUnaryCall<TResponse>(
null!,
GetMetadata(context),
null!,
null!,
null!);
var newOptions = context.Options.WithHeaders(_metadata!);
var newContext = new ClientInterceptorContext<TRequest, TResponse>(
context.Method,
context.Host,
newOptions);
return base.AsyncUnaryCall(request, newContext, continuation);
}
private async Task<Metadata> GetMetadata<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
where TRequest : class
where TResponse : class
{
try
{
if (!string.IsNullOrEmpty(await _authenticationManager.TryRefreshToken()))
_snackbar.Add("Refreshed Token.", Severity.Success);
var token = _authenticationManager.Token;
Console.WriteLine($"Token: {token}");
var headers = new Metadata();
if (!string.IsNullOrEmpty(token))
{
headers.Add(new Metadata.Entry("Authorization", $"Bearer {token}"));
Console.WriteLine("Set metadata");
var userIdentity = (await _authenticationStateProvider.GetAuthenticationStateAsync()).User.Identity;
if (userIdentity!.IsAuthenticated)
headers.Add(new Metadata.Entry("User", userIdentity.Name!));
}
else
{
await _authenticationManager.Logout();
_navigationManager.NavigateTo("/");
}
var callOptions = context.Options.WithHeaders(headers);
return _metadata = callOptions.Headers!;
}
catch (Exception ex)
{
throw new InvalidOperationException("Failed to add token to request headers", ex);
}
}
}
AksMessage
不等于AskMessage
。 - aepot