概要
ログインが必要なページなどには認可をするわけですが、それをAngularでやりました。
ついでに、認可が成功したらアクセスしようとしていたページへ飛ばすというのもやりました。
環境
- Angular 8.2.9
実装
認可(canActivate)
まずはGuardを作ります。ここではAuth
という名前で作っています。
ng g guard Auth
できたファイルを編集して認可をします。
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router, private authService: AuthService) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (!this.authService.isLogin()) {
this.router.navigate(['sign-in'], {queryParams: {history: state.url}});
return false;
}
return true;
}
}
canActivate
が認可判定をする本体で、true
を返せば認可、false
を返せば否認ということになります。私のプロジェクトではAuthService
というサービスで認証を行っていて、認証が失敗すればログインページにリダイレクトし、認証が成功すれば認可をするという実装になっています。
ログインページにリダイレクトする際に、クエリパラメータに現在のURLを付けています。例えば、/edit/12
というページからログインページにリダイレクトする際には、/
がエンコードされ、/sign-in?history=%2Fedit%2F12
にリダイレクトされます。
認証
リダイレクト先の処理は以下の通りになります。
(省略)
export class PageSignInComponent implements OnInit {
login: Login = {
email: '',
password: '',
};
private history: string;
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
private authService: AuthService,
private alertService: AlertService
) { }
ngOnInit() {
this.activatedRoute.queryParams.subscribe(
params => {
this.history = params.history;
}
);
}
onSubmit() {
this.authService.login(this.login)
.then((res) => {
this.router.navigate(this.history ? [this.history] : ['home']);
})
.catch((err) => {
console.error(err);
this.alertService.showErrorAlert('メールアドレスとパスワードに間違いがないか確認してください。');
});
}
}
ngOnInit
でクエリパラメータからリダイレクト前のURLを抜き出しています。ログインボタンが押され、onSubmit
で認証が成功し、リダイレクト前のURLがある場合にはそのURLに、なければ'home'
にリダイレクトさせています。
参考