Teruhiro Komaki

日々の暮らし、技術的な学び、そして仕事の記録

AngularでAuth0認証後に任意のページへ戻す方法(appStateの活用)

Angular 19(Standalone構成)環境にAuth0を導入した際の備忘録です。

Auth0 Angular SDKの loginWithRedirect() をデフォルト設定で使用すると、ログイン完了後にルート(/)へ強制的に遷移してしまう挙動があります。ユーザーが元いたページや特定のダッシュボードに戻れるよう、解決策をまとめます。

環境

teruhiro:~ $ ng version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 19.0.2
Node: 22.7.0
Package Manager: npm 10.9.1
OS: darwin arm64

Angular:
...

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.1900.2 (cli-only)
@angular-devkit/core         19.0.2 (cli-only)
@angular-devkit/schematics   19.0.2 (cli-only)
@schematics/angular          19.0.2 (cli-only)
実行環境のバージョン情報

Auth0 SDKのセットアップ

公式ドキュメント (Auth0 Angular SDK Quickstarts) のサンプルコードをベースに解説します。

provideAuth0() の追加

Angular 15以降のStandalone構成では、通常 app.config.ts にプロバイダー定義を記述します。

環境依存のURLハードコードを避けるため、redirect_uri には window.location.origin を使用するのがおすすめです。

// app.config.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideAuth0 } from '@auth0/auth0-angular';
import { AppComponent } from './app.component';

bootstrapApplication(AppComponent, {
  providers: [
    provideAuth0(<AuthConfig>{
      domain: 'xxx.jp.auth0.com',
      clientId: 'your-client-id',
      authorizationParams: {
        redirect_uri: 'http://localhost:4200/auth/auth0/callback',
      }
    }),
  ]
});
app.config.ts への Auth0 プロバイダー設定

課題:ログイン後にルートへ戻ってしまう

ドキュメントの基本的な例に倣って loginWithRedirect() をオプションなしで実装すると、以下のようになります。

onClickLogin() {
    // オプションなし
    this.authService.loginWithRedirect().subscribe()
}
オプションを指定しない loginWithRedirect() の実装例

実際の挙動と内部フロー

このコードを実行すると、Auth0側での認証、コールバックURLへの戻りを経て、最終的に http://localhost:4200 (ルート) にページが遷移します。

sequenceDiagram participant User participant App as Angular App participant Auth0 User->>App: ログインボタン押下 App->>Auth0: リダイレクト (loginWithRedirect) Auth0-->>User: ログイン画面表示 User->>Auth0: 認証情報入力 Auth0->>App: コールバック (/auth/auth0/callback?code=...) Note over App: SDKが認証情報を処理 App->>App: ルート (/) へ遷移 Note right of App: ※ここがデフォルト挙動
認証プロセスのシーケンス図:処理はブラウザとAuth0間で完結する

内部的な処理の流れは以下の通りです。

  1. ログインボタンをクリックする。
  2. Auth0のログインページ (https://xxx.jp.auth0.com/u/login?state=...) へ移動する。
  3. ログインする。
  4. アプリのコールバックURL (http://localhost:4200/auth/auth0/callback?code=...) に戻る。
  5. SDKが認証情報を処理する(内部で handleRedirectCallback 相当の処理)。
  6. SDKの仕様により、ターゲット未指定時はルート (/) へリダイレクトする。

解決策:appStateで遷移先を指定する

ログイン完了後に任意のページ(例: /private)や、ログインボタンを押した元のページに戻したい場合は、appState オプションを使用します。

onClickLogin() {
    this.authService.loginWithRedirect({
      appState: {
        // ログイン完了後に遷移させたいパスを指定
        target: '/private'
      }
    }).subscribe()
}
appState.target を指定した loginWithRedirect() の実装例

このように appState オブジェクト内に target プロパティを指定することで、意図したルートへ移動させることができます。

解説

Auth0 Angular SDKは、認証フロー開始時(loginWithRedirect 実行時)に渡された appState オブジェクトを保存し、コールバック後に復元する仕組みを持っています。

SDKは復元された appState.target の値を参照して Angular Router による遷移を行います。この値が未定義の場合のデフォルト値が / であるため、何も指定しないとトップページに戻る挙動となります。

Auth0コミュニティでも同様の議論がありました。

Redirect URI issue after successful login with @auth0/auth0-angular - Auth0 Community

補足:内部の仕組み (auth0-spa-js)

Angular SDKの内部で使用されている auth0-spa-js では、通常 handleRedirectCallback() を明示的に呼び出す必要がありますが、Angular SDK (@auth0/auth0-angular) ではこの処理が自動化されています。

URLクエリパラメータに ?state=...&code=... が含まれている場合、SDKがこれを検知して認証処理を行い、その後 appState.target で指定されたパスへ遷移させます。

参考までに、ライブラリを使わず auth0-spa-js を直接使った場合の処理イメージは以下のようになります。

// redirect to the Universal Login Page
document.getElementById('login').addEventListener('click', async () => {
  await auth0.loginWithRedirect();
});

// in your callback route (<MY_CALLBACK_URL>)
window.addEventListener('load', async () => {
  const redirectResult = await auth0.handleRedirectCallback();
  // logged in. you can get the user profile like this:
  const user = await auth0.getUser();
  console.log(user);
});
参考: auth0-spa-js での処理イメージ

コメントを投稿する

記事への感想やフィードバックなど、お気軽に書き込んでいただけると嬉しいです。

Googleログイン または 匿名 で利用できます。また、自分のコメントは後から編集・削除が可能です。

データは管理者が運用するサーバー(https://comentario.teruhirokomaki.com)に保存・管理されます。