Using an Angular service for OAuth2 authentication and authorization

OAuth2-based security is enabled in the backend API now. Angular can be modified to include code to generate and retrieve an access_token, use it to access protected resource endpoints. For this particular reason, an AuthService like the following one is used:

import {Injectable} from '@angular/core';
import {Router} from '@angular/router';
import { Cookie } from 'ng2-cookies';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthService {
constructor(
private router: Router, private http: Http){}

getAndSaveAccessToken(loginData){
let params = new URLSearchParams();
params.append('username',loginData.username);
params.append('password',loginData.password);
params.append('grant_type','password');

let headers = new Headers({'Content-type': 'application/x-www-form-
urlencoded; charset=utf-8',
'Authorization': 'Basic
'+btoa("angularjsapp:angularjs123")});
let options = new RequestOptions({ headers: headers });
this.http.post('http://localhost:8080/oauth/token',
params.toString(), options)
.map(res => res.json())
.subscribe(
data => this.saveToken(data),
err => console.log(err.body)
);
}

The preceding getAndSaveAccessToken method will access the /oauth/token endpoint with an authorization header with the value 'Basic '+base64encode("angularjsapp:angularjs123").  This will pass the grant_type parameter with the value's password, username, and the password of the user trying to log in. In return, the endpoint will return a JSON with access_token, refresh_token, expires_in, and others. This is depicted in the following code:

saveToken(token){
var expireDate = new Date().getTime() + (1000 * token.expires_in);
Cookie.set("access_token", token.access_token, expireDate);
this.router.navigate(['/']);
}

The preceding saveToken method will save the retrieved access_token from the preceding method into a browser cookie for later use. Consider the following code:

getToken() {
return Cookie.get('access_token');
}

The preceding getToken will return the access_token that's stored as a browser cookie:

checkCredentials(){
if (!Cookie.check('access_token')){
this.router.navigate(['/login']);
} else {
let headers = new Headers({'Content-type': 'application/x-www-form-
urlencoded; charset=utf-8',
'Authorization': 'Bearer '+Cookie.get('access_token')});
let options = new RequestOptions({ headers: headers });
this.http.get('http://localhost:8080/tweets', options)
.map(res => res.json())
.subscribe(
data => console.log(data),
err => {
console.log(err);
this.router.navigate(['/login']); }
);
}
}

The preceding checkCredentials method will first check whether a browser cookie for the access_token is already available; if found, it will check whether it is still valid by sending a dummy request. If either the access_token is not found or it is invalid, it will redirect to the login page. This is shown with the following code:

logout() {
Cookie.delete('access_token');
this.router.navigate(['/login']);
}

The preceding logout method deletes the access_token cookie and navigates to the login page.

In order to use this AuthService, there needs to be a login page defined. That is why /src/app/login.component.ts and /src/app/login.component.html have been created.

The following LoginComponent will use it as follows:

import { Component } from '@angular/core';
import { AuthService } from './auth.service';
import { NgForm } from '@angular/forms';

@Component({
selector: 'login-form',
providers: [AuthService],
templateUrl: './login.component.html'
})
export class LoginComponent {
public loginData = {username: "", password: ""};

constructor(private authService:AuthService) {}

login(ngForm: NgForm) {
this.authService.getAndSaveAccessToken(ngForm);
}
}

Use AuthService to get and save the access token with the username and password extracted from the following form:

<mat-card>
<form #loginForm="ngForm" (ngSubmit)="login(loginForm.value)">
<mat-card-header>
<mat-card-title><h2>Login</h2></mat-card-title>
</mat-card-header>
<mat-card-content>
<mat-form-field>
<input matInput placeholder="Username"
[(ngModel)]="loginData.username" required name="username"
#username/>
</mat-form-field>
<mat-form-field>
<input type="password" matInput placeholder="Password"
[(ngModel)]="loginData.password" required name="password"
#password/>
</mat-form-field>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary" type="submit"
[disabled]="!loginForm.form.valid">Login</button>
</mat-card-actions>
<mat-card-footer>
</mat-card-footer>
</form>
</mat-card>

The form is submitted to the LoginComponent.login method, and in TweetsService and UsersService, the AuthService.getToken method is used to submit the access_token as a header before sending requests to protected resource endpoints.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.178.9