我有 Angular 应用程序、用 ASP NET Core 编写的 BFF 和 SignalR 集线器。从 Angular 应用程序中,我想将请求发送到 BFF 端点,该端点将从 cookie 中提取访问令牌,然后将请求重定向到有效的 SignalR 集线器。
但问题是,当我通过我的 BFF 重定向到 SignalR 集线器时,在成功协商后,我的 Angular 应用程序想要与我的 BFF 而不是 SignalR 服务器对话。
public static async Task<IResult> GetChatHubInfo(HttpContext context, string negotiateVersion, CancellationToken cancellationToken)
{
var accessToken = context.GetTokenAsync("access_token");
context.Response.Headers.Authorization = $"Bearer {accessToken}";
return Results.Redirect($"https://localhost:7271/negotiate?negotiateVersion={negotiateVersion}", preserveMethod: true);
}
我使用 YARP 构建的反向代理来完成此操作。这是我的配置:
"ReverseProxy": {
"Routes": {
"ChatHub": {
"ClusterId": "ChatHub",
"Match": {
"Path": "/api/chathub/{*any}"
},
"Transforms": [
{
"PathRemovePrefix": "/api/chathub"
},
{
"RequestHeadersCopy": true
},
{
"RequestHeaderOriginalHost": true
},
{
"RequestHeader": "Upgrade",
"Set": "WebSocket"
},
{
"RequestHeader": "Connection",
"Set": "Upgrade"
},
{
"RequestHeaderRemove": "Cookie"
},
{
"X-Forwarded": "Set",
"For": "Append",
"Proto": "Append",
"Prefix": "Append",
"HeaderPrefix": "X-Forwarded-"
},
]
}
},
"Clusters": {
"ChatHub": {
"SessionAffinity": {
"Enabled": true,
"Policy": "HashCookie",
"FailurePolicy": "Redistribute",
"AffinityKeyName": "ChatHubAffinityKey",
"Cookie": {
"HttpOnly": true,
"IsEssential": true,
"SameSite": "Strict",
"SecurePolicy": "Always"
}
},
"LoadBalancingPolicy": "PowerOfTwoChoices",
"Destinations": {
"ChatHub/Dest1": {
"Address": "https://localhost:7140"
},
"HealthCheck": {
"Active": {
"Enabled": true,
"Interval": "00:00:15",
"Timeout": "00:00:10",
"Policy": "ConsecutiveFailures",
"Path": "/health"
},
"Passive": {
"Enabled": true,
"Policy": "TransportFailureRate",
"ReactivationPeriod": "00:00:15"
}
}
}
}
}
}
如您所见,我在代理时删除了所有 cookie。我在配置代理时提取访问令牌,如下所示:
services.AddReverseProxy()
.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"))
.AddTransforms(builder =>
{
builder.AddRequestTransform(async (ctx) =>
{
var accessToken = await ctx.HttpContext.GetTokenAsync("access_token");
ctx.ProxyRequest.Headers.Add("Authorization", $"Bearer {accessToken}");
});
});