Angular7でCognito認証を実装したい。
でも、よう分からん!
ということで、様々なサイトを参考に、ログイン処理やAPI処理をAngular7で実装してみました。
Angular7で新規プロジェクトを作りたい! Angularでプロジェクトを作成するのは非常に簡単です! ということで今回は、Angular7で新規プロジェクトを作成する方法を解説します! 前提 前提として、以下がインスト[…]
参考にしたサイト
以下のサイトを参考にさせていただきました。
Cognitoの設定
参考サイト通りにCognitoの設定を行います。
- ユーザプールの設定
- ユーザの追加
- API GateWayの設定
参考サイト通りにAngularの設定を行います。
参考ソース
以下に格納しています。以降は参考ソースの簡単な解説をしていきます。
ライブラリを入れる
1 2 |
> npm i --save amazon-cognito-identity-js > npm i --save aws-sdk |
- amazon-cognito-identity-js
- aws-sdk
「tsconfig.app.json」の設定
1 2 3 4 5 6 7 8 9 10 11 |
{ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "../out-tsc/app", "types": ["node"] }, "exclude": [ "test.ts", "**/*.spec.ts" ] } |
エラーがいっぱい出ました。イライラ度マックスです。 AngularにAWSのライブラリを入れました。入れた理由は「Angular×Cognito」を試してみたかったからです。 ライブラリを入れると、アホみたいにエラーが出ました。[…]
「polyfills.ts」の設定
1 2 3 4 5 |
// "global is not defined"の対応 (window as any).global = window; // "Buffer is not defined"の対応 global.Buffer = global.Buffer || require('buffer').Buffer; |
Angular7で開発中のことです。以下のようなエラーが出ました。 「Uncaught ReferenceError: global is not defined」。 殺意が芽生えますが、いったん落ち着いて対処法を検討してみまし[…]
「environment.ts」の設定
1 2 3 4 5 6 |
export const environment = { production: false, region: 'ap-northeast-1', userPoolId: 'ap-northeast-1_XXXXX', clientId: 'XXXXXXXXXXXXXXXXXXXX' }; |
「app.module.ts」の設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { AppRoutingModule } from './app-routing.module'; import { CognitoService } from './service/cognito.service'; import { PetService } from './service/pet.service'; import { AppComponent } from './app.component'; import { LoginComponent } from './login/login.component'; import { PetlistComponent } from './petlist/petlist.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { NoopInterceptor } from './service/pet.service'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; @NgModule({ declarations: [ AppComponent, LoginComponent, PetlistComponent, DashboardComponent ], imports: [ BrowserModule, FormsModule, AppRoutingModule, HttpClientModule, ReactiveFormsModule ], providers: [{ provide: HTTP_INTERCEPTORS, useClass: NoopInterceptor, multi: true, }, CognitoService, PetService], bootstrap: [AppComponent] }) export class AppModule { } |
「app-routing.module.ts」の設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { DashboardComponent } from './dashboard/dashboard.component'; import { PetlistComponent } from './petlist/petlist.component'; import { LoginComponent } from './login/login.component'; const routes: Routes = [ { path: '', redirectTo: '/login', pathMatch: 'full' }, { path: 'dashboard', component: DashboardComponent }, { path: 'petlist', component: PetlistComponent }, { path: 'login', component: LoginComponent, pathMatch: 'full' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } |
「cognito.service.ts」の設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
import { Injectable } from '@angular/core'; import { environment } from './../../environments/environment'; import { CognitoUserPool, CognitoUser, AuthenticationDetails } from 'amazon-cognito-identity-js'; import * as AWS from 'aws-sdk'; @Injectable() export class CognitoService { private userPool: CognitoUserPool; private poolData: any; public cognitoCreds: AWS.CognitoIdentityCredentials; private token: string; constructor() { AWS.config.region = environment.region; this.poolData = { UserPoolId: environment.userPoolId, ClientId: environment.clientId }; this.userPool = new CognitoUserPool(this.poolData); } // ログイン処理 login(username: string, password: string): Promise<any> { const userData = { Username: username, Pool: this.userPool, Storage: localStorage }; const cognitoUser = new CognitoUser(userData); const authenticationData = { Username: username, Password: password, }; const authenticationDetails = new AuthenticationDetails(authenticationData); return new Promise((resolve, reject) => { cognitoUser.authenticateUser(authenticationDetails, { onSuccess: function (result) { alert('LogIn is success!'); console.log('id token + ' + result.getIdToken().getJwtToken()); console.log('access token + ' + result.getAccessToken().getJwtToken()); console.log('refresh token + ' + result.getRefreshToken().getToken()); resolve(result); }, onFailure: function (err) { alert(err); console.log(err); reject(err); } }); }); } // ログイン済確認処理 isAuthenticated(): Promise<any> { const cognitoUser = this.userPool.getCurrentUser(); return new Promise((resolve, reject) => { if (cognitoUser === null) { reject(cognitoUser); } cognitoUser.getSession((err, session) => { if (err) { reject(err); } else { if (!session.isValid()) { reject(session); } else { resolve(session); } } }); }); } // トークン取得処理 getCurrentUserIdToken(): any { const cognitoUser = this.userPool.getCurrentUser(); if (cognitoUser != null) { cognitoUser.getSession((err, session) => { if (err) { alert(err); return; } else { this.token = session.getIdToken().getJwtToken(); } }); } return this.token; } // ログイン処理 logout() { console.log('LogOut!'); const currentUser = this.userPool.getCurrentUser(); if (currentUser) { currentUser.signOut(); } } } |
「pet.service.ts」の設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; import { Observable } from 'rxjs'; import { catchError, map, tap } from 'rxjs/operators'; import { Pet } from '../pet'; import { CognitoService } from './cognito.service'; const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; @Injectable() export class PetService { private Url = 'https://XXXXX.execute-api.ap-northeast-1.amazonaws.com/test/pets'; // URL to web api constructor( private http: HttpClient, private cognito: CognitoService) { } /** GET pets from the server */ getPets(): Observable<Pet[]> { return this.http.get<Pet[]>(this.Url); } } @Injectable() export class NoopInterceptor implements HttpInterceptor { constructor(private cognito: CognitoService) { } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // サービスから認証ヘッダーを取得します。 const authHeader = this.cognito.getCurrentUserIdToken(); // 新しいヘッダーを加えたリクエストを複製します。 const authReq = req.clone({ headers: req.headers.set('Authorization', authHeader) }); // オリジナルのリクエストの代わりに複製したリクエストを投げます。 return next.handle(authReq); } } |
おすすめ本
Angularの勉強をするならこの2冊がおすすめです!
まとめ
今回は、「Angular7×Cognito」の処理を実装してみました。
Angular7で実装されているものが少ないので、ネットの情報通りに実装してもうまくいかないことが多々あります。
Angular7でCognitoの処理を実装したい方は何かしら参考になるかと思います!