话不多说直接上代码。
csusing System; using System.Threading.Tasks; using Grpc.Core; using Grpc.Core.Interceptors; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; public class GrpcTokenInterceptor : Interceptor { const string ACCESS_TOKEN = "access_token"; private readonly ILogger<GrpcTokenInterceptor> _logger; private readonly IHttpContextAccessor _contextAccessor; public GrpcTokenInterceptor(ILogger<GrpcTokenInterceptor> logger, IHttpContextAccessor contextAccessor) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); ; _contextAccessor = contextAccessor ?? throw new ArgumentNullException(nameof(contextAccessor)); } public async Task<string?> GetTokenAsync() => await _contextAccessor.HttpContext!.GetTokenAsync(ACCESS_TOKEN); ClientInterceptorContext<TRequest, TResponse> passToken<TRequest, TResponse>( ClientInterceptorContext<TRequest, TResponse> context ) where TRequest : class where TResponse : class { var token = GetTokenAsync().Result; if (token is not null) { var headers = context.Options.Headers; if (headers is null) { _logger.LogInformation("Header is null, create new one"); headers = new Metadata { { "Authorization", $"Bearer {token}" } }; context = new ClientInterceptorContext<TRequest, TResponse>( context.Method, context.Host, context.Options.WithHeaders(headers) ); } else { headers.Add("Authorization", $"Bearer {token}"); } } return context; } public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>( TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation) { context = passToken(context); var call = continuation(request, context); return new AsyncUnaryCall<TResponse>( call.ResponseAsync, call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose); } }
需要在 Startup.cs
中配置:
csharp// ConfigureServices 中 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddTransient<GrpcTokenInterceptor>(); services.AddGrpcClient<Your.GrpcClient>(options => options.Address = "grpc url") .AddInterceptor<GrpcExceptionInterceptor>();