如何将自定义 headers 添加到 SignalR 的 Typescript 客户端?
How do I add custom headers to SignalR's Typescript client?
我正在尝试在 header 中传递不记名令牌以授权客户端连接。 SignalR 集线器通过从 header 获取承载令牌来授权客户端。我无法修改 SingalR 中心代码以使用查询字符串来获取令牌,也无法使用 built-in JWT 令牌功能。
如何向 SignalR typescript 客户端添加自定义 header?
我唯一能想到的就是重写 HttpClient 以添加 header 但是我不确定这是否可行或如何执行此操作。
我正在使用 Angular 8 中的 @microsoft/signalr 和最新的 @microsoft/signalr 包。
您可以在建立连接时在选项中添加自定义的HttpClient。
看起来像这样:
class CustomHttpClient extends DefaultHttpClient {
public send(request: HttpRequest): Promise<HttpResponse> {
request.headers = { ...request.headers, "customHeader": "value" };
return super.send(request);
}
}
let hubConnection = new HubConnectionBuilder()
.withUrl(url, { httpClient: new CustomHttpClient() })
.build();
可以从 DefaultHttpClient
继承并在您的发送中调用 DefaultHttpClient 的发送,因此您不需要自己实现 Http 调用。
第一个 class 支持已通过 IHttpConnectionOptions
上的 headers
属性 在 @microsoft/signalr 包的 5.0 或更高版本中实现,请参阅 https://github.com/dotnet/aspnetcore/issues/14588 已解决 GitHub 问题。
如果这只是为了传递不记名令牌,则无需进行自定义 headers,要传递访问令牌,您可以使用带有 IHttpConnectionOptions 的 withUrl 重载,此接口具有可以像这样使用的 accessTokenFactory :
yourAuthServicePromise.then(
(data) => {
if (data.['result']['accessToken']) {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('https://SIGNALR_SERVER_HUB_URL', {
accessTokenFactory: () => {
return data.['result']['accessToken'];
}
} as signalR.IHttpConnectionOptions)
.build();
this.hubConnection.start()
}
}
);
不要忘记在 hub 服务器中启用 cors 策略以允许 JS 客户端来源
我需要与@Brennan 的答案一模一样的东西。
我刚刚填补了一些缺失的空白,以获得更多的复制和粘贴答案。我正在使用它并且它有效,谢谢@Brennan
import * as signalR from "@aspnet/signalr";
// You can create a factory which signalR will used to generate an access token on each request
const getBearerToken = () => "MY TOKEN GETTING FUNCTION"
// This is a custom method which creates all the headers I need for my authentication
const getAuthHeaders = () => ({ collection: "", of: "", headers:""})
// As per @Brennan's answer I used his advice and extened the default one
class CustomHttpClient extends signalR.DefaultHttpClient {
constructor() {
super(console); // the base class wants an signalR.ILogger, I'm not sure if you're supposed to put *the console* into it, but I did and it seemed to work
}
// So far I have only overriden this method, and all seems to work well
public async send(request: signalR.HttpRequest): Promise<signalR.HttpResponse> {
var authHeaders = getAuthHeaders(); // These are the extra headers I needed to put in
request.headers = { ...request.headers, ...authHeaders };
// Now we have manipulated the request how we want we can just call the base class method
return super.send(request);
}
}
let connection = new signalR.HubConnectionBuilder()
.withUrl(`${apiUrl}/web-sockets/stripeHub`, {
accessTokenFactory: getBearerToken, // I also needed this, but you may not need it
httpClient: new CustomHttpClient(), // This is the CustomClient we defined above which adds the headers to each request going out
})
.build();
创建集线器连接构建器时有一个名为 headers
的选项。并且此选项仅在您使用 @microsoft/signalr
npm 包时可用。这是 signalr 的活跃回购,旧的 (@aspnet/signalr) 已存档。
所以使用新的 npm 包,你可以像下面那样做
let connection = new signalR.HubConnectionBuilder()
.withUrl("/chat", {
headers: {
"custom-header-name": "value"
},
withCredentials: (true/false) // if you dont mention this value (if undefined by default it will set to true (which i didnt wanted in my case)
})
.build();
注意: 请记住,默认情况下自动重新连接为 false,因此请添加 withUrl().withAutomaticReconnect()
如果你愿意。
更多关于 options interface
我正在尝试在 header 中传递不记名令牌以授权客户端连接。 SignalR 集线器通过从 header 获取承载令牌来授权客户端。我无法修改 SingalR 中心代码以使用查询字符串来获取令牌,也无法使用 built-in JWT 令牌功能。
如何向 SignalR typescript 客户端添加自定义 header?
我唯一能想到的就是重写 HttpClient 以添加 header 但是我不确定这是否可行或如何执行此操作。
我正在使用 Angular 8 中的 @microsoft/signalr 和最新的 @microsoft/signalr 包。
您可以在建立连接时在选项中添加自定义的HttpClient。
看起来像这样:
class CustomHttpClient extends DefaultHttpClient {
public send(request: HttpRequest): Promise<HttpResponse> {
request.headers = { ...request.headers, "customHeader": "value" };
return super.send(request);
}
}
let hubConnection = new HubConnectionBuilder()
.withUrl(url, { httpClient: new CustomHttpClient() })
.build();
可以从 DefaultHttpClient
继承并在您的发送中调用 DefaultHttpClient 的发送,因此您不需要自己实现 Http 调用。
第一个 class 支持已通过 IHttpConnectionOptions
上的 headers
属性 在 @microsoft/signalr 包的 5.0 或更高版本中实现,请参阅 https://github.com/dotnet/aspnetcore/issues/14588 已解决 GitHub 问题。
如果这只是为了传递不记名令牌,则无需进行自定义 headers,要传递访问令牌,您可以使用带有 IHttpConnectionOptions 的 withUrl 重载,此接口具有可以像这样使用的 accessTokenFactory :
yourAuthServicePromise.then(
(data) => {
if (data.['result']['accessToken']) {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl('https://SIGNALR_SERVER_HUB_URL', {
accessTokenFactory: () => {
return data.['result']['accessToken'];
}
} as signalR.IHttpConnectionOptions)
.build();
this.hubConnection.start()
}
}
);
不要忘记在 hub 服务器中启用 cors 策略以允许 JS 客户端来源
我需要与@Brennan 的答案一模一样的东西。
我刚刚填补了一些缺失的空白,以获得更多的复制和粘贴答案。我正在使用它并且它有效,谢谢@Brennan
import * as signalR from "@aspnet/signalr";
// You can create a factory which signalR will used to generate an access token on each request
const getBearerToken = () => "MY TOKEN GETTING FUNCTION"
// This is a custom method which creates all the headers I need for my authentication
const getAuthHeaders = () => ({ collection: "", of: "", headers:""})
// As per @Brennan's answer I used his advice and extened the default one
class CustomHttpClient extends signalR.DefaultHttpClient {
constructor() {
super(console); // the base class wants an signalR.ILogger, I'm not sure if you're supposed to put *the console* into it, but I did and it seemed to work
}
// So far I have only overriden this method, and all seems to work well
public async send(request: signalR.HttpRequest): Promise<signalR.HttpResponse> {
var authHeaders = getAuthHeaders(); // These are the extra headers I needed to put in
request.headers = { ...request.headers, ...authHeaders };
// Now we have manipulated the request how we want we can just call the base class method
return super.send(request);
}
}
let connection = new signalR.HubConnectionBuilder()
.withUrl(`${apiUrl}/web-sockets/stripeHub`, {
accessTokenFactory: getBearerToken, // I also needed this, but you may not need it
httpClient: new CustomHttpClient(), // This is the CustomClient we defined above which adds the headers to each request going out
})
.build();
创建集线器连接构建器时有一个名为 headers
的选项。并且此选项仅在您使用 @microsoft/signalr
npm 包时可用。这是 signalr 的活跃回购,旧的 (@aspnet/signalr) 已存档。
所以使用新的 npm 包,你可以像下面那样做
let connection = new signalR.HubConnectionBuilder()
.withUrl("/chat", {
headers: {
"custom-header-name": "value"
},
withCredentials: (true/false) // if you dont mention this value (if undefined by default it will set to true (which i didnt wanted in my case)
})
.build();
注意: 请记住,默认情况下自动重新连接为 false,因此请添加 withUrl().withAutomaticReconnect()
如果你愿意。
更多关于 options interface