認証は難しい場合があり、アプリで必要になるたびに車輪の再発明を行うのは確かに楽しいことではありません。 ありがたいことに、さまざまなサービスとツールが私たちの重労働を処理することができます。 Firebase を使用した認証の実装についてはすでに説明したので、別の方法であるAuth0について見ていきましょう。 Auth0は、認証プロバイダーに期待されるすべての機能(ソーシャルログイン、電子メール/パスワードログイン、承認ルールなど)を提供する非常に強力なソリューションです。

この投稿では、 Auth0 Lockウィジェットを使用します。これにより、認証のためにアプリ内にポップアップを埋め込むことができます。 Auth0のホストされたログインページで認証を実装することもできます。その場合は、このガイドを参照してください。

この投稿では、Angular2+アプリの認証について説明します。

設定

まず最初に、Auth0アカウントを作成してから、新しいシングルページWebアプリケーションクライアントを作成する必要があります。

クライアントが作成されると、好みに応じて設定を構成できるようになります。 重要なことの1つは、Angularアプリの実際のログインコールバックルートを反映するコールバックURLを追加することです。 ここでは、 login ルートを作成するため、許可される唯一のコールバックURLとしてhttp://localhost:4200/loginを追加します。 Auth0は、認証後にリダイレクトされます。

クライアントの設定では、ドメインおよびクライアントID情報にもアクセスできます。 その情報をアプリのenvironment.tsファイルに追加します。

environment.ts
export const environment = {
  production: false,
  auth0: {
    domain: 'your-awesome-domain.auth0.com',
    clientId: 'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
    callbackURL: 'http://localhost:4200/login'
  }
};

プロジェクトには、 auth0-js auth0-lock angle2-jwtの3つの追加パッケージも必要です。 npmまたはYarnを使用して、それらをプロジェクトにインストールしましょう。

$ yarn add auth0-js auth0-lock angular2-jwt

# or, using npm:
$ npm install auth0-js auth0-lock angular2-jwt

次に、アプリのビルドに含まれるスクリプトのリストにauth0.min.jsを追加します。

.angular-cli.json
...,
"scripts": [
  "../node_modules/auth0-js/build/auth0.min.js"
],
...

テナント

Auth0を使用すると、さまざまな展開環境(開発本番ステージングなど)に対応する複数のテナントを作成できます。各テナントは独自のドメイン名を取得します(例: :my-app-dev.auth0.comおよびmy-app.auth0.com)。 このようにして、本番用に別のクライアントを作成できます。必要なのは、本番環境ファイルに別のドメイン名、クライアントID、およびコールバックURLを入力することだけです。

コンポーネントとルーティングの設定

アプリにhomeコンポーネントとloginコールバックコンポーネントの2つのコンポーネントを追加します。 Angular CLI を使用して、新しいコンポーネントを簡単に生成できます。

$ ng g c home
$ ng g c login

次に、簡単なルーティングモジュールを設定しましょう。

app.routing.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { LoginComponent } from './login/login.component';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'login', component: LoginComponent }
];

認証サービス

また、AngularCLIを使用してAuthサービスを作成しましょう。

$ ng g s auth

この時点で、ルーティングモジュールがアプリモジュールにインポートされていることと、認証サービスがアプリモジュールによっても提供されていることを確認する必要があります。

認証サービスの設定を始めましょう。

auth.service.ts
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { environment } from '../environments/environment';

import { tokenNotExpired } from 'angular2-jwt';
import Auth0Lock from 'auth0-lock';
@Injectable()
export class AuthService {
  auth0Options = {
    theme: {
      logo: '/assets/alligator-logo.svg',
      primaryColor: '#DFA612'
    },
    auth: {
      redirectUrl: environment.auth0.callbackURL,
      responseType: 'token id_token',
      audience: https://${environment.auth0.domain}/userinfo,
      params: {
        scope: 'openid profile'
      }
    },
    autoclose: true,
    oidcConformant: true,
  };
  lock = new Auth0Lock(
    environment.auth0.clientId,
    environment.auth0.domain,
    this.auth0Options
  );
  constructor(private router: Router) {
    this.lock.on('authenticated', (authResult: any) => {
      console.log('Nice, it worked!');
      this.router.navigate(['/']); // go to the home route
      // ...finish implementing authenticated
    });
this.lock.on('authorization_error', error => {
  console.log('something went wrong', error);
});  }
  login() {
    this.lock.show();
  }
  logout() {
    // ...implement logout
  }

注意すべき点がいくつかあります。

  • まず、 Auth0Lock の新しいインスタンスを定義します。これは、クライアントID、ドメイン、および構成オブジェクトを取得します。 利用可能な構成オプションはたくさんあります。ここでは、必要なオプションに加えて、ロックウィジェットのスタイルを設定するためのいくつかのテーマオプションも追加しました。
  • オプションでは、 scopes キーを使用して、戻すデータの種類も指定します。 ここでは、デフォルトの openid に加えて、profile情報を取得することにも関心があります。
  • サービスのコンストラクターでは、ロックインスタンスでauthenticatedまたはauthorization_errorイベントのいずれかをリッスンします。 authenticated イベントのコールバックには、認証が成功したときのロジックが含まれます。
  • ログインメソッドは、ロックインスタンスでshowメソッドを呼び出すのと同じくらい簡単に実装できます。
  • 戻って、logoutメソッドとisAuthenticatedメソッドの実装を完了する必要があります。

これで、ホームコンポーネントにauthサービスを挿入できます。

home.component.ts
import { Component } from '@angular/core';

import { AuthService } from '../auth.service';
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html'
})
export class HomeComponent {

そして、ログインボタンとログアウトボタンをテンプレートに追加しましょう。

home.component.html
<button
  *ngIf="!auth.isAuthenticated()"
  (click)="auth.login()">
  Sign Up or Login
</button>

<button
  *ngIf="auth.isAuthenticated()"
  (click)="auth.logout()">
  Logout
</button>

基本認証サービスが整っているので、Auth0埋め込みはすでに機能しており、サインアップまたはログインできます。

Lock widget example

プロファイル、IsAuthenticated、ログアウト

認証サービスの実装を完了しましょう。 この例では、Auth0がローカルストレージに返すJSONWebトークンを保存します。 そのトークンは、バックエンドAPIへのHTTPリクエストで Bearer プレフィックスを使用して、Authorizationヘッダーに追加できます。 その後、トークンが有効であることを確認するのはバックエンドの責任です。 また、 scopes を使用してリクエストしたアカウントのプロファイル情報を取得し、ローカルストレージに保存します。

まず、成功した認証済みイベントのロジック:

auth.service.ts(部分的)
this.lock.on('authenticated', (authResult: any) => {
  this.lock.getUserInfo(authResult.accessToken, (error, profile) => {
    if (error) {
      throw new Error(error);
    }

localStorage.setItem('token', authResult.idToken);
localStorage.setItem('profile', JSON.stringify(profile));
this.router.navigate(['/']);

ここでは、ロックインスタンスで getUserInfo を呼び出し、成功した認証から返されたアクセストークンを渡します。 getUserInfo を使用すると、ユーザーのプロファイル情報にアクセスできます。


isAuthenticated

isAuthenticated メソッドは、認証済みの使用済みかどうかをアプリが認識し、結果としてUIを適応させるのに役立ちます。

これを実装するには、angle2-jwttokenNotExpiredメソッドを使用します。 トークンがない場合、またはトークンの有効期限が切れている場合は、falseを返します。

isAuthenticated() {
  return tokenNotExpired();
}

ログインアウト

認証にJWTを使用することはステートレスであるため、ログアウトするために必要なのは、ローカルストレージからトークンとプロファイルを削除することだけです。

auth.service.ts
logout() {
  localStorage.removeItem('profile');
  localStorage.removeItem('token');
}

🔑そして、あなたはそれを持っています! アプリの簡単な認証。