ng2-signalr
ng2-signalr copied to clipboard
How to set Authorization Header ?
I am using ng2-signalr
in ionic 2. Issue is that i don't know how to set authorization header. I have search but didn't find any example.
My code for connecting to server hub.
let options: IConnectionOptions = { qs:{userId:1}, url: "http://192.168.0.211:44337"};
console.log("Stage 1");
//Header for 'this.singalR.connect'
this.signalR.connect(options)
.then((connection) => {
console.log("Client Id: " + connection.id);
}, (err) => {
console.log("SignalR Error: " + JSON.stringify(err));
});
How to set below header ?
var headers = new Headers({
'Content-Type': "application/json",
"Authorization": 'Bearer ' + accessToken //accessToken contain bearer value.
});
Note: Before implementing Authorization same code working fine as i don't need to set authorization header.
you need to send the token as a query parameter
instead of
qs:{userId:1}
write
qs:{userId:1, token: 'your token'}
@HNeukermans Thanks for response.
Issue it that is have two signalr client , one is in simple angularjs and other is ionic 2 .
In Simple Angularjs i'm doing following to set the header. (Which is working).
$.signalR.ajaxDefaults.headers = new Headers({
'Content-Type': "application/json",
"Authorization": 'Bearer ' + accessToken //accessToken contain bearer value.
});
I'm wondering if there is way to send headers just like above . If i go for query string option that is what you suggested then i have to change a lot of code on server side as well as on simple angularjs signalr client .
Is there any other way ?
Hi @Usman235,,
thx a ton. I didn't even know this existed inside signalr. Sorry, my fault... Seems like a next ng2-signalr super feature !! As a workaround inside your typescript project you can always do
declare var $: any;
$.signalR.ajaxDefaults.headers = new Headers({
'Content-Type': "application/json",
"Authorization": 'Bearer ' + accessToken //accessToken contain bearer value.
});
If you feel comfortable writing typescript,.. Would you like to try to add the feature to ng2-signalr yourself ?
From my part, I will add this feature, the moment I find some free time...
Maybe a small question to you about the ajaxDefaults? The headers you add there: Are these send with every signalr request you do? If you change the ajaxDefaults headers when you already have an ongong connection,are the changes taken into account ? Or do you need to create a newly instantiated connection for that ?
@HNeukermans sorry for late response.
I'm beginner to typescript . :)
The headers you add there: Are these send with every signalr request you do?
Yes headers are send with every signalr request.
If you change the ajaxDefaults headers when you already have an ongong connection,are the changes taken into account ? Or do you need to create a newly instantiated connection for that ?
Yes if i change ajaxDefaults
headers changes are automatically applied i don't need to newly instantiated connection.
Unfortunately below didn't work for me.
declare var $: any;
$.signalR.ajaxDefaults.headers = new Headers({
'Content-Type': "application/json",
"Authorization": 'Bearer ' + accessToken //accessToken contain bearer value.
});
As i have to meet deadline so i implemented qs
method which you suggested me . And at server side added a new middlerware which check for every request if token is in query string
simple it just add that token in request header.
Found a solution. You need to use the window object to get access to jQuery, you just have to cast it to an any.
let $ = (<any>window).$;
$.signalR.ajaxDefaults.headers = {
'Content-Type': "application/json",
"Authorization": 'Bearer ' + this.oauthService.getAccessToken()
};
How does the real-life implementation look like? I having issues with injecting my oauthService there... Are you putting it into the createConfig(): SignalRConfiguration ?
We created a custom service where the SignalR and OAuthService are injected. Below is a basic example where the ISignalRConnection is provided through an Observable. This way, if the connection is interrupted and re-establised, you are able to automatically resubscribe to the new connection.
import { Injectable, OnInit } from '@angular/core';
import { SignalR, ISignalRConnection } from 'ng2-signalr';
import { Notice } from "app/feed/notice/notice.model";
import { Observable } from "rxjs/Observable";
import { Subject } from "rxjs/Subject";
import { OAuthService } from "angular-oauth2-oidc/dist";
@Injectable()
export class SignalrService {
private subject: Subject<ISignalRConnection>;
public connection: Observable<ISignalRConnection>;
constructor(private signalR: SignalR, private oauthService: OAuthService) {
this.subject = new Subject<ISignalRConnection>();
this.connection = this.subject.asObservable().shareReplay(1);
if (navigator.onLine) {
this.connect();
}
}
private connect() {
// Set auth headers.
let $ = (<any>window).$;
$.signalR.ajaxDefaults.headers = {
'Content-Type': "application/json",
"Authorization": 'Bearer ' + this.oauthService.getAccessToken()
};
let promise = this.signalR.connect();
promise
.then(x => {
this.subject.next(x);
x.errors.subscribe(y => {
if (y.message.includes(`Couldn't reconnect within the configured timeout`)) {
this.reconnect();
}
})
})
.catch(x => this.reconnect());
}
private reconnect() {
let ms = 3000;
console.log(`Manual reconnect after ${ms}ms`);
setTimeout(() => this.connect(), ms)
}
}
And to listen for a message, inject this SignalrService and subscribe to the connection Observable:
this.signalrService
.connection
.subscribe(connection => connection
.listenFor('your-message')
.subscribe((yourMessage: IYourMessage) => {
// do something
}));
from jquery.signalR.core.js: // With sse or ws, access_token in request header is not supported if (connection.transport && connection.accessToken) { if (connection.transport.name === "serverSentEvents" || connection.transport.name === "webSockets") { url += "&access_token=" + window.encodeURIComponent(connection.accessToken); } }
rely on $.signalR.ajaxDefaults.headers will only enable longPolling, but sse or ws negotiate request will return 401, I think relying on query params is better.
Hello,
Is it already possible to send an Authorization header something like this:
(headers: request.headers.set('Authorization', 'Bearer ' + token) <-- using a JWT token here.
instead of via query string parameters?
In my angular app i use an interceptor where i add a header to all my http requests. I did not test it yet but maybe if i try it with an interceptor it could work? this week i will try that and let you know... fingers crossed :)
Edit: Maybe this will help if we are bound to query string parameters. -> https://stackoverflow.com/a/57460785