angular2-jwt
Advanced tools
Comparing version 0.1.19 to 0.1.20
import { Http, Request, RequestOptions, RequestOptionsArgs, Response } from '@angular/http'; | ||
import { Observable } from 'rxjs/Observable'; | ||
import 'rxjs/add/observable/fromPromise'; | ||
import 'rxjs/add/operator/mergeMap'; | ||
export interface IAuthConfig { | ||
@@ -39,2 +41,3 @@ globalHeaders: Array<Object>; | ||
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response>; | ||
private requestWithToken(req, token); | ||
get(url: string, options?: RequestOptionsArgs): Observable<Response>; | ||
@@ -41,0 +44,0 @@ post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>; |
@@ -14,2 +14,4 @@ "use strict"; | ||
var Observable_1 = require('rxjs/Observable'); | ||
require('rxjs/add/observable/fromPromise'); | ||
require('rxjs/add/operator/mergeMap'); | ||
/** | ||
@@ -91,2 +93,3 @@ * Sets up the authentication configuration. | ||
AuthHttp.prototype.request = function (url, options) { | ||
var _this = this; | ||
if (typeof url === 'string') { | ||
@@ -100,3 +103,13 @@ return this.get(url, options); // Recursion: transform url from String to Request | ||
var req = url; | ||
if (!tokenNotExpired(undefined, this.config.tokenGetter())) { | ||
var token = this.config.tokenGetter(); | ||
if (token.then) { | ||
return Observable_1.Observable.fromPromise(token) | ||
.flatMap(function (jwtToken) { return _this.requestWithToken(req, jwtToken); }); | ||
} | ||
else { | ||
return this.requestWithToken(req, token); | ||
} | ||
}; | ||
AuthHttp.prototype.requestWithToken = function (req, token) { | ||
if (!tokenNotExpired(undefined, token)) { | ||
if (!this.config.noJwtError) { | ||
@@ -109,3 +122,3 @@ return new Observable_1.Observable(function (obs) { | ||
else { | ||
req.headers.set(this.config.headerName, this.config.headerPrefix + this.config.tokenGetter()); | ||
req.headers.set(this.config.headerName, this.config.headerPrefix + token); | ||
} | ||
@@ -112,0 +125,0 @@ return this.http.request(req); |
import "core-js"; | ||
import {AuthConfig} from "./angular2-jwt"; | ||
import {AuthConfig, AuthHttp} from "./angular2-jwt"; | ||
import {tokenNotExpired} from "./angular2-jwt"; | ||
import {JwtHelper} from "./angular2-jwt"; | ||
import {Observable} from "rxjs"; | ||
@@ -144,1 +145,30 @@ | ||
}); | ||
describe("AuthHttp", () => { | ||
describe("request", () => { | ||
it("handles tokenGetters returning string", () => { | ||
let authHttp: AuthHttp = new AuthHttp(new AuthConfig({ | ||
tokenGetter: () => validToken | ||
}), null); | ||
spyOn(authHttp, "requestWithToken").and.stub(); | ||
authHttp.request(null); | ||
expect(authHttp["requestWithToken"]).toHaveBeenCalledWith(null, validToken); | ||
}); | ||
it("handles tokenGetters returning Promise\<string\>", (done: Function) => { | ||
let authHttp: AuthHttp = new AuthHttp(new AuthConfig({ | ||
tokenGetter: () => Promise.resolve(validToken) | ||
}), null); | ||
spyOn(authHttp, "requestWithToken").and.returnValue(Observable.of("")); | ||
authHttp.request(null).subscribe(() => { | ||
expect(authHttp["requestWithToken"]).toHaveBeenCalledWith(null, validToken); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
import { provide, Injectable } from '@angular/core'; | ||
import { Http, Headers, Request, RequestOptions, RequestOptionsArgs, RequestMethod, Response } from '@angular/http'; | ||
import { Observable } from 'rxjs/Observable'; | ||
import 'rxjs/add/observable/fromPromise'; | ||
import 'rxjs/add/operator/mergeMap'; | ||
@@ -120,3 +122,13 @@ // Avoid TS error "cannot find name escape" | ||
let req: Request = url as Request; | ||
if (!tokenNotExpired(undefined, this.config.tokenGetter())) { | ||
let token: string & Promise<string> = this.config.tokenGetter(); | ||
if(token.then) { | ||
return Observable.fromPromise(token) | ||
.flatMap((jwtToken: string) => this.requestWithToken(req, jwtToken)); | ||
} else { | ||
return this.requestWithToken(req, token); | ||
} | ||
} | ||
private requestWithToken(req: Request, token: string): Observable<Response> { | ||
if (!tokenNotExpired(undefined, token)) { | ||
if (!this.config.noJwtError) { | ||
@@ -128,4 +140,5 @@ return new Observable<Response>((obs: any) => { | ||
} else { | ||
req.headers.set(this.config.headerName, this.config.headerPrefix + this.config.tokenGetter()); | ||
req.headers.set(this.config.headerName, this.config.headerPrefix + token); | ||
} | ||
return this.http.request(req); | ||
@@ -132,0 +145,0 @@ } |
{ | ||
"name": "angular2-jwt", | ||
"version": "0.1.19", | ||
"version": "0.1.20", | ||
"description": "Helper library for handling JWTs in Angular 2", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -38,3 +38,3 @@ # angular2-jwt [![npm version](https://img.shields.io/npm/v/angular2-jwt.svg)](https://www.npmjs.com/package/angular2-jwt) [![license](https://img.shields.io/npm/l/angular2-jwt.svg)](https://www.npmjs.com/package/angular2-jwt) | ||
```ts | ||
import {AuthHttp, AuthConfig, AUTH_PROVIDERS} from 'angular2-jwt'; | ||
import { AuthHttp, AuthConfig, AUTH_PROVIDERS } from 'angular2-jwt'; | ||
@@ -91,2 +91,4 @@ ... | ||
```ts | ||
import { provideAuth } from 'angular2-jwt'; | ||
... | ||
@@ -96,15 +98,10 @@ | ||
HTTP_PROVIDERS, | ||
provide(AuthHttp, { | ||
useFactory: (http) => { | ||
return new AuthHttp(new AuthConfig({ | ||
headerName: YOUR_HEADER_NAME, | ||
headerPrefix: YOUR_HEADER_PREFIX, | ||
tokenName: YOUR_TOKEN_NAME, | ||
tokenGetter: YOUR_TOKEN_GETTER_FUNCTION, | ||
globalHeaders: [{'Content-Type':'application/json'}], | ||
noJwtError: true, | ||
noTokenScheme: true | ||
}), http); | ||
}, | ||
deps: [Http] | ||
provideAuth({ | ||
headerName: YOUR_HEADER_NAME, | ||
headerPrefix: YOUR_HEADER_PREFIX, | ||
tokenName: YOUR_TOKEN_NAME, | ||
tokenGetter: YOUR_TOKEN_GETTER_FUNCTION, | ||
globalHeaders: [{'Content-Type':'application/json'}], | ||
noJwtError: true, | ||
noTokenScheme: true | ||
}) | ||
@@ -122,6 +119,6 @@ ]) | ||
getThing() { | ||
var myHeader = new Headers(); | ||
let myHeader = new Headers(); | ||
myHeader.append('Content-Type', 'application/json'); | ||
this.authHttp.get('http://example.com/api/thing', { headers: myHeader} ) | ||
this.authHttp.get('http://example.com/api/thing', { headers: myHeader }) | ||
.subscribe( | ||
@@ -134,3 +131,3 @@ data => this.thing = data, | ||
// Pass it after the body in a POST request | ||
this.authHttp.post('http://example.com/api/thing', 'post body', { headers: myHeader} ) | ||
this.authHttp.post('http://example.com/api/thing', 'post body', { headers: myHeader }) | ||
.subscribe( | ||
@@ -193,31 +190,70 @@ data => this.thing = data, | ||
## Checking Login to Hide/Show Elements and Handle Routing | ||
## Checking Authentication to Hide/Show Elements and Handle Routing | ||
The `tokenNotExpired` function can be used to check whether a JWT exists in local storage, and if it does, whether it has expired or not. If the token is valid, `tokenNotExpired` returns `true`, otherwise it returns `false`. | ||
The router's `@CanActivate` lifecycle hook can be used with `tokenNotExpired` to determine if a route should be accessible. This lifecycle hook is run before the component class instantiates. If `@CanActivate` receives `true`, the router will allow navigation, and if it receives `false`, it won't. | ||
> **NOTE**: The `@CanActivate` lifecycle hook has been deprecated in the latest Angular 2 router. To use it, you need to `import` from `@angular/router-deprecated`. | ||
> **Note:** `tokenNotExpired` will by default assume the token name is `id_token` unless a token name is passed to it, ex: `tokenNotExpired('token_name')`. This will be changed in a future release to automatically use the token name that is set in `AuthConfig`. | ||
```ts | ||
// auth.service.ts | ||
import { tokenNotExpired } from 'angular2-jwt'; | ||
... | ||
@Component({ | ||
selector: 'secret-route' | ||
}) | ||
loggedIn() { | ||
return tokenNotExpired(); | ||
} | ||
@View({ | ||
template: `<h1>If you see this, you have a JWT</h1>` | ||
}) | ||
... | ||
``` | ||
@CanActivate(() => tokenNotExpired()) | ||
The `loggedIn` method can now be used in views to conditionally hide and show elements. | ||
class SecretRoute {} | ||
```html | ||
<button id="login" *ngIf="!auth.loggedIn()">Log In</button> | ||
<button id="logout" *ngIf="auth.loggedIn()">Log Out</button> | ||
``` | ||
You can pass a different `tokenName` for `@CanActivate` to use as the first argument to the function. If you wish to define your own function for `tokenNotExpired` to use, pass `null` first and then the function. | ||
To guard routes that should be limited to authenticated users, set up an `AuthGuard`. | ||
```ts | ||
// auth-guard.service.ts | ||
import { Injectable } from '@angular/core'; | ||
import { Router } from '@angular/router'; | ||
import { CanActivate } from '@angular/router'; | ||
import { Auth } from './auth.service'; | ||
@Injectable() | ||
export class AuthGuard implements CanActivate { | ||
constructor(private auth: Auth, private router: Router) {} | ||
canActivate() { | ||
if(this.auth.loggedIn()) { | ||
return true; | ||
} else { | ||
this.router.navigate(['unauthorized']); | ||
return false; | ||
} | ||
} | ||
} | ||
``` | ||
With the guard in place, you can use it in your route configuration. | ||
```ts | ||
... | ||
import { AuthGuard } from './auth.guard'; | ||
export const routes: RouterConfig = [ | ||
{ path: 'admin', component: AdminComponent, canActivate: [AuthGuard] }, | ||
{ path: 'unauthorized', component: UnauthorizedComponent } | ||
]; | ||
... | ||
``` | ||
## Contributing | ||
@@ -224,0 +260,0 @@ |
@@ -14,2 +14,3 @@ { | ||
"angular2-jwt.ts", | ||
"angular2-jwt.spec.ts", | ||
"typings/browser.d.ts", | ||
@@ -16,0 +17,0 @@ "custom.d.ts" |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
147721
22
2875
288