Right. You probably don’t even want to really access it from the pages themselves (although you can do that if you wish). Typically, all the pages care about is “are we authenticated?”.
I use JWT for authentication, and here’s my approach. You should be able to adapt it to your situation.
Sink
This is a service that interacts with ionic-storage to persist credentials across app restarts. If you don’t want to do that, just store the tokens temporarily.
export class Sink {
private _jwt: string;
private _authNotifier: ReplaySubject<boolean> = new ReplaySubject<boolean>(1);
constructor(private _db: Storage) {
// load from storage
}
authenticationNotifier(): Observable<boolean> {
return this._authNotifier;
}
// don't call this until the authentication notifier has fired true
getJwt(): string {
return this._jwt;
}
setJwt(jwt: string): Promise<void> {
this._jwt = jwt;
this._authNotifier.next(!!jwt);
// save it in storage, return resultant promise
}
}
AuthedHttp
This is a wrapper for Http
that handles adding authorization headers. Mostly fairly boring boilerplate, but it can inject Sink
in its constructor, get the authentication token, add it to headers, and use that in requests, all transparently to consumers.
App component
constructor(sink: Sink) {
sink.authenticationNotifier().subscribe((authed) => {
if (authed) {
this.rootPage = AuthedPage;
} else {
this.rootPage = UnauthedPage;
}
});
}
Now any time anybody anywhere calls setJwt(somethingValid)
, the root page automatically flips to the authorized home page. If setJwt(null)
is called, the page automatically goes to the unauthed page. Logout becomes dead simple; no fooling with navigation controllers at all.
Login page
constructor(private _http: Http, private _sink: Sink, private _nav: NavController) {
}
doLogin(): void {
this._http.get('url-for-auth-token').subscribe((rsp) => {
let authtoken = magicallyExtractToken(rsp);
this._sink.setJwt(authtoken).then(() => {
this._nav.pop();
});
});
}