A Token Walks Into a BarΒ ...
SPA
Ado Kukic
Developer Evangelist
Auth0
@kukicado
SPA (Angular)
Security Best Practices
...
https://ng-thor.com
User
https://api.ng-thor.com
https://app.ng-thor.com
ngThor
OK, ngThor
JSON Web Tokens
JWT's (RFC 7519) are an open industry standardΒ method for representing claims securely between two parties.
JSON Web Tokens
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOmZhbHNlfQ.uI_rNanTsZ_wFa1VnICzq2txKeYPArda5QLdVeQYFGI
How is a Drivers License like a JSON Web Token?
Header
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOmZhbHNlfQ.uI_rNanTsZ_wFa1VnICzq2txKeYPArda5QLdVeQYFGI
Drivers License
New York State
{
"alg":"HS256",
Β "typ":"JWT"
}
Payload
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOmZhbHNlfQ.uI_rNanTsZ_wFa1VnICzq2txKeYPArda5QLdVeQYFGI
Picture
Name
Address
Demographics
Restrictions
{
Β "sub": "1234567890",
Β "name": "Thor Odinson",
Β "admin": true
}
Signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOmZhbHNlfQ.uI_rNanTsZ_wFa1VnICzq2txKeYPArda5QLdVeQYFGI
UV Light
Hologram
HMACSHA256( header + "." + payload, "lokisucks" )
π
/v1/orders
{ "status": 401 }
/v1/auth
{
Β "status": 200,
"jwt" :"eyJhbGciOiJIU.."
}
/v1/orders
-H "Authorization: Bearer eyJhbGciOiJ..."
{ Β "status": 200, "order_id" : 138, Β "total_cost" : 27.99, Β ... }
JWT and Angular
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class MyAppService {
private url = 'https://api.ng-thor.com/v1';
constructor(private http: HttpClient) { }
login() {
return this.http.get(`${this.url}/auth`);
}
getOrders() {
return this.http.get(`${this.url}/orders`);
}
}
HTTP Client Library
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders} from '@angular/common/http';
@Injectable()
export class MyAppService {
private url = 'https://api.ng-thor.com/v1';
constructor(private http: HttpClient) { }
login() {
return this.http.get(`${this.url}/auth`);
}
getOrders() {
let headers = new HttpHeaders(
{
Authorization: "Bearer " + localStorage.getItem("jwt")
}
);
return this.http.get(`${this.url}/orders`, {headers: headers});
}
}
HTTP Client Library
HTTP Interceptors
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class JWTInterceptor implements HttpInterceptor {
constructor() {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${localStorage.getItem("jwt")}`
}
});
return next.handle(request);
}
}
HTTP Interceptors
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { AuthService } from './auth.service';
import { Router } from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
if (!this.authService.authenticated) {
this.router.navigate(['/login']);
return false;
}
return true;
}
}
Route Guards
import { Routes, RouterModule, CanActivate } from '@angular/router';
import { LoginComponent } from './components/login.component';
import { CheckoutComponent } from './components/checkout.component';
import { AuthGuard } from './auth/auth.guard';
const routes: Routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'checkout',
component: CheckoutComponent,
canActivate: [
AuthGuard
]
}
];
Route Guards
Summary
JSON Web Tokens are excellent for securing Angular applications.
Angular's excellent HTTP Library makes it easy to work with JWT's.
Single Page Application security is mainly concerned with authorization.Β
A security guard couldn't stop Thor, but your server can refuse requests without valid JWT's.
Thank You
@kukicado
Β
http://bit.ly/ng-spa-demo
http://bit.ly/ng-auth-series
A Token Walks Into a Bar
By Ado Kukic
A Token Walks Into a Bar
- 1,382