Sorry for delay, here is how I do it:
auth.service.ts
export class AuthService {
authChanged: EventEmitter<any> = new EventEmitter();
postLogin(f: ILoginForm) {
return this.http.post('/login', f)
.map(res => res.json())
.subscribe(data => this._checkLoginResponse(data));
}
/**
* Check Login Result
* @param data
*/
private _checkLoginResponse(data: any) {
// If Successful Login
if (data.data && data.meta && data.meta.token) {
// Set User & Token
localStorage.setItem('inctoken', data.meta.token);
localStorage.setItem('incuser', JSON.stringify(data.data));
// Emit Auth & User Events
this.authChanged.emit(this.getUser());
// Show OK Login Flash Message
this.flash.success('You have been logged in successfully.');
// Navigate Home
this.injector.get(Router).navigate(['/']);
}
}
/**
* Logout of Interface
* @returns boolean
*/
logout(withMsg = false): boolean {
// # Remove Token & User from LS
localStorage.removeItem('inctoken');
localStorage.removeItem('incuser');
// Emit Auth Events
this.authChanged.emit(false);
// Show Flash Message
if (withMsg)
this.flash.info('You have been logged out.', 'OK.');
// Redirect to Login Page
this.injector.get(Router).navigate(['/login']);
return true;
}
}
Then any component can inject AuthService and know when the authedUser changes, logs out, etc. Take my Navbar for example:
navbar.component.ts
export class NavbarComponent {
/**
* Authed User
*/
authedUser: IUser;
constructor(private authService: AuthService) {
this.authService.authChanged
.subscribe((user?: IUser) => {
// user will be false if logged out
// or user object if logged in.
this.authedUser = user;
});
}
}
Then in my navbar template I can choose to display things based on auth status:
<nav class="navbar">
<!-- Truncated -->
<ul class="menu-item"
*ngIf="authedUser">
<li><img [src]="authedUser.avatar"></li>
<!-- Whatever -->
</ul>
<ul class="menu-item"
*ngIf="!authedUser">
<li><a [routerLink]="['/login']">Login</a></li>
<!-- Whatever -->
</ul>
</nav>
Obviously a lot of these classes are truncated for brevity.
If you're curious about how the token gets sent in the header, here is a light example of the HttpClient class I created (truncated for brevity):
http.service.ts
export class HttpClient {
constructor(private http: Http) {
// ...
}
/**
* Get
* @param url
* @returns {Observable<any>}
*/
get(url): Observable<any> {
// Create New Headers
let headers = new Headers();
// Set Authorization Header
this._createAuthorizationHeader(headers);
// Create Observable to Return to Calling Service.
// We Dont Just Return the HTTP Observable Because
// We Need to Subscribe Here to Catch The Errors That
// May Be Thrown, Otherwise, Every Service Would Need
// To Call The Handle Errors Method
return Observable.create((observer) => {
// Fire Http GET Request, Subscribe & Catch Errors
return this.http.get(this.baseUrl + url, {
headers: headers
}).subscribe(
data => observer.next(data), // Emit Data Returned
err => this.handleError(err), // Catch Errors
() => observer.complete() // Emit Completed
);
});
}
/**
* Create Authorization Header
* @param {Headers} headers
*/
private _createAuthorizationHeader(headers: Headers) {
// If We Have A Token, Append It. The
// API Server Will Determine Its Validity
if (localStorage.getItem('inctoken')) {
headers.append('Authorization', 'Bearer: ' + localStorage.getItem('inctoken'));
}
}
}
Then in my other components I can just inject my HttpClient class and use it to have token automatically placed in headers, I.E.
some.component.ts
export class SomeComponent {
constructor(private http: HttpClient) {
// ...
}
private _getSomeData() {
return this.get('/someurl')
.map(res => res.json();
}
}