Token based authentication service for Angular2 with multiple user support. Angular2-Token works best with the devise token auth gem for Rails. Angular2-Token is currently in Beta. Any contribution is much appreciated.
A sample application can be found here.
- Webpack (SystemJS not tested)
-
Install Angular2-Token via NPM with
npm install angular2-token
-
Import and add
Angular2TokenService
to your main module.Angular2TokenService
depends onHttpModule
andRouterModule
, so make sure you import them too.import { Angular2TokenService } from 'angular2-token'; @NgModule({ imports: [ BrowserModule, HttpModule, RouterModule ], declarations: [ AppComponent ], providers: [ Angular2TokenService ], bootstrap: [ AppComponent ] })
-
Inject
Angular2TokenService
into your main component and call.init()
.constructor(private _tokenService: Angular2TokenService) { this._tokenService.init(); }
Quickstart includes the necessary forms and routing to quickly use Angular2-Token with your Project. A live demo can be found here.
Quickstart is currently in αlpha, please use with caution.
- Add
A2tUiModule
to your main module.import { Angular2TokenService, A2tUiModule } from 'angular2-token'; @NgModule({ imports: [ BrowserModule, HttpModule, RouterModule, A2tUiModule ], declarations: [ AppComponent ], providers: [ Angular2TokenService ], bootstrap: [ AppComponent ] })
The A2tUiModule
adds the following routes to your project:
Route | Description |
---|---|
session/sign-in |
Sign in form |
session/sign-up |
Sign out form |
session/reset-password |
Reset password form |
session/update-password |
Update password for email redirect |
On successful sign in the user will be redirect to restricted
.
- Configuration
- Service Methods
- HTTP Service Wrapper
- Multiple User Types
- Route Guards
- Advanced Usage
- Common Problems
- Development
Configuration options can be passed as Angular2TokenOptions
via .init()
.
constructor(private _tokenService: Angular2TokenService) {
this._tokenService.init({
apiBase: null,
apiPath: null,
signInPath: 'auth/sign_in',
signInRedirect: null,
signInStoredUrlStorageKey: null,
signOutPath: 'auth/sign_out',
validateTokenPath: 'auth/validate_token',
signOutFailedValidate: false,
registerAccountPath: 'auth',
deleteAccountPath: 'auth',
registerAccountCallback: window.location.href,
updatePasswordPath: 'auth',
resetPasswordPath: 'auth/password',
resetPasswordCallback: window.location.href,
oAuthBase: window.location.origin,
oAuthPaths: {
github: 'auth/github'
},
oAuthCallbackPath: 'oauth_callback',
oAuthWindowType: 'newWindow',
oAuthWindowOptions: null,
userTypes: null,
globalOptions: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
});
}
Options | Description |
---|---|
apiBase?: string |
Sets the server for all API calls. |
apiPath?: string |
Sets base path all operations are based on |
signInPath?: string |
Sets path for sign in |
signInRedirect?: string |
Sets redirect path for failed CanActivate |
signInStoredUrlStorageKey?: string |
Sets locale storage key to store URL before displaying signIn page |
signOutPath?: string |
Sets path for sign out |
validateTokenPath?: string |
Sets path for token validation |
signOutFailedValidate?: boolean |
Signs user out when validation returns a 401 status |
registerAccountPath?: string |
Sets path for account registration |
deleteAccountPath?: string |
Sets path for account deletion |
registerAccountCallback?: string |
Sets the path user are redirected to after email confirmation for registration |
updatePasswordPath?: string |
Sets path for password update |
resetPasswordPath?: string |
Sets path for password reset |
resetPasswordCallback?: string |
Sets the path user are redirected to after email confirmation for password reset |
userTypes?: UserTypes[] |
Allows the configuration of multiple user types (see Multiple User Types) |
globalOptions?: GlobalOptions |
Allows the configuration of global options (see below) |
oAuthBase?: string |
Configure the OAuth server (used for backends on a different url) |
oAuthPaths?: { [key:string]: string } |
Sets paths for sign in with OAuth |
oAuthCallbackPath?: string |
Sets path for OAuth sameWindow callback |
oAuthWindowType?: string` |
Window type for Oauth authentication |
oAuthWindowOptions?: { [key:string]: string } |
Set additional options to pass into window.open() |
Options | Description |
---|---|
headers?: { [key:string]: string; } |
Define custom global headers as hashmap. Be careful when overwriting the default options, devise token auth will refuse requests without the Content-Type -Header set |
Further information on paths/routes can be found at devise token auth
Once initialized Angular2TokenService
offers methods for session management.
The signIn method is used to sign in the user with email address and password.
The optional parameter type
specifies the name of UserType used for this session.
signIn({email: string, password: string, userType?: string}): Observable<Response>
this._tokenService.signIn({
email: '[email protected]',
password: 'secretPassword'
}).subscribe(
res => console.log(res),
error => console.log(error)
);
The signOut method destroys session and session storage.
signOut(): Observable<Response>
this._tokenService.signOut().subscribe(
res => console.log(res),
error => console.log(error)
);
Sends a new user registration request to the Server.
registerAccount({email: string, password: string, passwordConfirmation: string, userType?: string}): Observable<Response>
this._tokenService.registerAccount({
email: '[email protected]',
password: 'secretPassword',
passwordConfirmation: 'secretPassword'
}).subscribe(
res => console.log(res),
error => console.log(error)
);
Deletes the account for the signed in user.
deleteAccount(): Observable<Response>
this._tokenService.deleteAccount().subscribe(
res => console.log(res),
error => console.log(error)
);
Validates the current token with the server.
validateToken(): Observable<Response>
this._tokenService.validateToken().subscribe(
res => console.log(res),
error => console.log(error)
);
Updates the password for the logged in user.
updatePassword({password: string, passwordConfirmation: string, passwordCurrent: string, userType?: string, resetPasswordToken?: string}): Observable<Response>
this._tokenService.updatePassword({
password: 'newPassword',
passwordConfirmation: 'newPassword',
passwordCurrent: 'oldPassword',
resetPasswordToken: 'resetPasswordToken',
}).subscribe(
res => console.log(res),
error => console.log(error)
);
Request a password reset from the server.
resetPassword({email: string, userType?: string}): Observable<Response>
this._tokenService.resetPassword({
email: '[email protected]',
}).subscribe(
res => console.log(res),
error => console.log(error)
);
Initiates OAuth authentication flow. Currently, it supports two window modes:
newWindow
(default) and sameWindow
(settable in config as oAuthWindowType
).
-
When
oAuthWindowType
is set tonewWindow
,.signInOAuth()
opens a new window and returns an observable. -
When
oAuthWindowType
is set tosameWindow
,.signInOAuth()
returns nothing and redirects user to auth provider. After successful authentication, it redirects back tooAuthCallbackPath
. Application router needs to intercept this route and callprocessOAuthCallback()
to fetchAuthData
from params.
signInOAuth(oAuthType: string)
this._tokenService.signInOAuth(
'github'
).subscribe(
res => console.log(res),
error => console.log(error)
);
Fetches AuthData from params sent via OAuth redirection in sameWindow
flow.
processOAuthCallback()
Callback route:
RouterModule.forRoot([
{ path: 'oauth_callback', component: OauthCallbackComponent }
])
Callback component:
@Component({
template: ''
})
export class OauthCallbackComponent implements OnInit {
constructor(private _tokenService: Angular2TokenService) {}
ngOnInit() {
this._tokenService.processOAuthCallback();
}
}
Angular2TokenService
wraps all standard Angular2 Http Service calls for authentication and token processing.
If apiPath
is configured it gets added in front of path.
get(url: string, options?: RequestOptionsArgs): Observable<Response>
post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>
put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>
delete(url: string, options?: RequestOptionsArgs): Observable<Response>
patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>
head(url: string, options?: RequestOptionsArgs): Observable<Response>
options(url: string, options?: RequestOptionsArgs): Observable<Response>
this._tokenService.get('my-resource/1').map(res => res.json()).subscribe(
res => console.log(res),
error => console.log(error)
);
An array of UserType
can be passed in Angular2TokenOptions
during init()
.
The user type is selected during sign in and persists until sign out.
.currentUserType
returns the currently logged in user.
this._tokenService.init({
userTypes: [
{ name: 'ADMIN', path: 'admin' },
{ name: 'USER', path: 'user' }
]
});
this._tokenService.signIn({
email: '[email protected]',
password: 'secretPassword',
userType: 'ADMIN'
})
this._tokenService.currentUserType; // ADMIN
Angular2-Token implements the CanActivate
interface, so it can directly be used as a route guard.
If the signInRedirect
option is set the user will be redirected on a failed (=false) CanActivate using Router.navigate()
.
It currently does not distinguish between user types.
const routerConfig: Routes = [
{
path: '',
component: PublicComponent
}, {
path: 'restricted',
component: RestrictedComponent,
canActivate: [Angular2TokenService]
}
];
More advanced methods can be used if a higher degree of customization is required.
More customized requests can be send with the .request()
-function. It accepts the RequestOptionsArgs-Interface.
More information can be found in the Angular2 API Reference here.
request(options: RequestOptionsArgs): Observable<Response>
this._tokenService.request({
method: RequestMethod.Post,
url: 'my-resource/1',
data: mydata
});
Returns true
if a user is signed in. It does not distinguish between user types.
userSignedIn(): boolean
Returns current user type as string like specified in the options.
get currentUserType(): string
Returns current user data as returned by devise token auth.
This variable is null
after page reload until the .validateToken()
call is answerd by the backend.
get currentUserData(): UserData
Returns current authentication data which are used to set auth headers.
get currentAuthData(): AuthData
Returns current authentication data as an HTTP ready Header object.
get currentAuthHeaders(): Header
If you want to redirect to the protected URL after signing in, you need to set signInStoredUrlStorageKey
and in your code you can do something like this
this._tokenService.signIn({
email: '[email protected]',
password: 'secretPassword'
}).subscribe(
res => {
// You have to add Router DI in your component
this.router.navigateByUrl(localStorage.getItem('redirectTo'));
},
error => console.log(error)
);
If you are using CORS in your Rails API make sure that Access-Control-Expose-Headers
includes access-token
, expiry
, token-type
, uid
, and client
.
For the rack-cors gem this can be done by adding the following to its config.
More information can be found here.
ruby :expose => ['access-token', 'expiry', 'token-type', 'uid', 'client']
Make sure that your projects includes some kind of routing.
If the package is installed from Github specified in the package.json, you need to build the package locally.
cd ./node_modules/angular2-token
npm install
npm run build
npm test
Test config files based on Angular2 Webpack Starter by AngularClass
The MIT License (see the LICENSE file for the full text)