![見出し画像](https://assets.st-note.com/production/uploads/images/104787916/rectangle_large_type_2_91f3ad27495d204f319ab4d031a66aef.png?width=1200)
Angular×DRF_SPAのログイン機能でやっていること #372
ログイン機能の流れを学んだので整理しておきます。
フロントエンドはAngular、バックエンドはDRFを使っています。
①IDとパスワードを入力して「ログイン」
最初はもちろんIDとパスワードの入力から始まります。ログインボタンを押下するとAngularのHttpClientのpostメソッドで、バックエンド側にリクエストを送信します。
②バックエンドで認証とトークン生成
バックエンド(DRF)でリクエストを受けたら、IDとパスワードの認証を行います。認証が通ればAPIトークンを生成し、レスポンスとしてフロントエンドに返します。
以下はemailがID代わりになっている実装例です。
class SignIn(APIView):
def post(self, request):
serializer = SignInSerializer(data=request.data)
if not serializer.is_valid():
return self.__response_400('不正なパラメータが含まれています。')
email = request.data['email']
password = request.data['password']
try:
user = User.objects.get(email=email)
if not user:
return self.__response_400('アカウントが無効です。')
if not user.check_password(password):
return self.__response_400('パスワードが間違っています。')
user.api_token = gen_api_token(user.email, password)
user.save(update_fields=['api_token'])
serializer = UserSerializer(user, many=False)
data = serializer.data
data['status'] = 'valid'
return Response(serializer.data)
except User.DoesNotExist:
return self.__response_400('メールアドレスまたはパスワードが間違っています。')
gen_api_token()というメソッドでAPIトークンを生成・更新し、フロントエンドに返しています。
③取得したトークンでトップページに遷移
バックエンドから帰ってきたユーザー情報とAPIトークンをフロントで受け取って処理します。先ほどのIDとパスワードをpostリクエストで送信したところからの一連です。
public doLogin(email: string, password: string): Observable<any> {
const endPoint = this.environmentService.getAPIEndPoint();
const path = `${endPoint}/signin`;
const params = {
email: email,
password: password
};
return this.httpClient.post(path, params).pipe(
map((res: any) => {
this.deleteSession();
this._user = User.fromJson(res);
this._apiToken = res.api_token;
this.cookieService.put('token', this._apiToken);
})
);
先にdeleteSession()で古いユーザー情報とAPIトークンを削除し、新たに取得したものを格納します。APIトークンの扱いにはAngularのCookieServiceを活用しています。
これでログイン後の画面に遷移する準備が整いました。
doLoginの呼び出し元コードを以下のようにします。
this.sessionService.doLogin(this.emailFormControl.value, this.passwordFormControl.value).subscribe(
res => {
if (this.sessionService.apiToken !== null) {
this.router.navigateByUrl('path/to/top/page/');
});
} else {
this.isLoginFail = true;
this.isRequested = false;
}
細かい部分は省略していますが、とりあえずapiTokenに値が挿入されていればトップページにリダイレクトする仕組みになっています。
トップページに表示するデータを取得する際にHttpClientのgetメソッドを使いますが、そのリクエストヘッダー(X-HTTP-AUTH-TOKEN)に先ほど生成したトークンをセットします。
以下のイメージです。トークンのセットはthis.sessionService.authHeaderで実現しています。
public getEnterprises(): Promise<Enterprise[]> {
const endPoint = this.environmentService.getAPIEndPoint();
const path = `${endPoint}/users/enterprises/`;
return this.httpClient
.get(path, this.sessionService.authHeader)
.pipe(
map((res: string[]) => {
return res.map(x => Enterprise.fromJson(x));
}),
catchError(error => {
console.warn(error);
return observableThrowError('errorだよ');
})
)
.toPromise();
メソッドの中身は以下です。HttpHeaders()はAngularが用意してくれています。
public get authHeader() {
const token = this.apiToken ? this.apiToken : 'xx';
return {
headers: new HttpHeaders().set('X-HTTP-AUTH-TOKEN', token)
};
ここまでお読みいただきありがとうございました!