2. Discussion Agenda
• OAuth 2.0 Background
• What is a JWT?
• JWT Authentication Token Lifecycle
• HTTP Interceptor design pattern in Angular
2
3. Background: OAuth 2.0 Bearer Tokens
• OAuth 2.0 is a Token Based Authentication Framework typically used with SPA
apps.
• OAuth 2.0 uses encrypted/encoded token strings instead of passing usernames and
passwords.
• An OAuth 2.0 infrastructure issues tokens to users after authentication. The token
must be saved locally on the client and authorizes the user’s access to resources
(APIs, etc.) for a set amount of time.
• Upon token expiration, the user must log in again to access resources (APIs) with
subsequent HTTP Requests.
• A common way of accessing OAuth 2.0 APIs is using a “Bearer Token”. This is a
single string which acts as the authentication of the API request, sent in an HTTP
“Authorization” header.
3
4. Sample Bearer Token Payload
In an HTTP Request sent to an API using
OAuth 2.0, the Authorization header
contains the Bearer Token as shown here
4
Bearer Tokens are encrypted/encoded token strings
labeled “Bearer” which are used to validate
authentication claims on the server side.
Bearer 0b79bab50daca910b000d4f1a2b675d604257e42…
5. JWT is a Token Format used to implement OAuth 2.0
• OAuth 2.0 Bearer Tokens need to contain user identity and timeout information.
• Bearer Tokens are issued by the authorization server, expire and can be reused.
• Bearer Tokens need to be signed so that the resource server can validate them
• JWTs are used with SPA apps as Bearer Tokens for OAuth 2.0 authentication.
5
User
Enterprise
login
API
6. JWT = JSON Web Tokens
• JSON Web Tokens are called JWTs for abbreviation.
• JWTs are digitally signed JSON payloads. Payloads typically contain user identification info
and a lifespan timestamp for authentication.
• As discussed, JWTs are often created by authentication servers to use as Bearer Tokens.
• Bearer Tokens expire, so Angular apps can use JWTs to define a user session.
• JWTs are convenient, because to confirm a session, all the authentication code needs to do
is validate the token’s signature.
• JWTs contain an encoded header, an encoded payload, and are digitally signed by
encrypting the header and payload with a secret key.
• The authentication code signs and validates JWT signatures, so only the server
(resource server and authenticating server) needs to know the secret key.
6
8. 3 Components of a JWT
1. The Header defines the Algorithm and Token Type. (JWT in this case)
{
“alg”: “HS256”,
“typ”: “JWT”
}
2. The Payload contains user information necessary to support the Session. The
Payload typically contains a user ID and an expiration timestamp for authentication.
The Payload is -not- encrypted so it is important to mind its contents!
{
“userId”: “023040506”,
“timeout”: “1234567890000”
}
3. The Signature contains a Message Authentication Code string. To produce a
valid signature, you need the Payload and Header, and a Secret Key which is unique
to your app.
8
9. The JWT Signature is used to validate claims
• The authenticating party (authentication server and resource server) holds a secret key
string, which is used to create and validate the signatures of JWTs.
• The authentication server uses the SHA256 encryption algorithm and its personal
secret key string to create JWT signatures using the below algorithm:
HMACSHA256( base64UrlEncode(header) + ".“ base64UrlEncode(payload), secret )
• From the browser, the user logs in once through the authentication server, then receives
a personal unique JWT (a “Bearer Token”) with the above unique signature back via an
HTTP Response.
• The browser then only needs to save the JWT Bearer Token in memory, and it can be
used to validate every HTTP Request with the secret key string, thus defining a
session.
9
10. JWT Bearer Token Lifecycle
10
ServerBrowser
1: User sends username and password to server via
browser 2: Server validates
username and
password.
3: Server generates
JWT Bearer Token
using secret key
4: Server sends Bearer Token back to
browser. Does not include password in
Bearer Token payload
5: Browser saves
Bearer Token in
local storage
6: Browser sends Bearer Token back to server with
HTTP Requests 7: Server decodes
Bearer Token, checks
the timestamp and
validates the signature
using the secret key
8: Server sends back HTTP Response data
if the session is valid.
A valid session = timestamp
has not expired and Bearer
Token signature is valid!
eyJhbGciOiJIUzI1NiIsI
nR5cCI6IkpXVCJ9.eyJ
zdWIiOiIxMjM0NTY3O
DkwIiwibmFtZSI6Ikpva
G4gRG9lIiwiYWRtaW4i
OnRydWV9.TJVA95Or
M7E2cBab30RMHrHDc
EfxjoYZgeFONFh7HgQ
Auth
API
11. Angular HTTP Interceptor Design Pattern – Step 0
Install a library to your app to use to check if a JWT is expired. I
like angular2-jwt.
npm i --save angular2-jwt
11
12. Angular HTTP Interceptor Design Pattern – Step 1
Use angular2-jwt in a service.
// src/app/auth/auth.service.ts
import { Injectable } from '@angular/core';
import tokenNotExpired from ‘angular2-jwt’;
@Injectable()
export class AuthService {
public getToken(): string {
return localStorage.getItem('token');
}
public isAuthenticated(): boolean {
// get the token
const token = this.getToken();
// return a boolean reflecting whether or not the token is expired
return tokenNotExpired(null, token);
}
}
12
13. Angular HTTP Interceptor Design Pattern – Step 2
Create an Interceptor which adds the JWT from local storage to the Authorization
Header in any HTTP Request sent.
// src/app/auth/token.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { AuthService } from './auth/auth.service';
import { Observable } from 'rxjs/Observable’;
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(public auth: AuthService) {}
intercept(request: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.auth.getToken()}`
}
});
return next.handle(request);
}
}
13
14. Angular HTTP Interceptor Design Pattern – Step 3
Add our new Interceptor class to the HTTP Interceptors service provider (and add the HTTP
Interceptors service to your app if needed).
// src/app/app.module.ts
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenInterceptor } from './../auth/token.interceptor’;
@NgModule({
bootstrap: [AppComponent],
imports: [...],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptor,
multi: true
}
]
})
export class AppModule {}
14
15. Angular HTTP Interceptor Design Pattern – Step 4
Now when we make any HTTP request, the user’s token will be attached
automatically.
Our TokenInterceptor was added to the HTTP Interceptors array by making
the existing HTTP_Interceptors array use our new class.
Now the application-scoped HTTP Interceptors service will use our new class,
and the Authorization Header with our Bearer Token will be added to every
HTTP Request.
15