マジックリンク(ワンタイムトークン)
ワンタイムパスワード(OTP)と同様に、ワンタイムトークンはユーザーのアイデンティティを検証するために使える、もう一つのパスワードレス認証 (Authentication) 方法です。 このトークンは一定期間のみ有効で、エンドユーザーのメールアドレスに紐付けられます。
新しいユーザーをアプリケーション / 組織に招待したいが、事前にアカウント作成を求めたくない場合があります。 また、パスワードを忘れてしまい、メールで素早く本人確認をしてサインイン / パスワードリセットをしたい場合もあるでしょう。 このような場合、アプリケーションは「マジックリンク」をメールで送信できます。リンクをクリックすると、即座に認証 (Authentication) されます。
アプリケーション開発者はワンタイムトークンを使ってマジックリンクを作成し、エンドユーザーのメールアドレスに送信できます。
ワンタイムトークンのフロー
ワンタイムトークンを使った認証 (Authentication) フローのシーケンス図は以下の通りです:
実装ガイド
Logto はマジックリンクの実装を簡単にするために、Management API と Experience API の両方を提供しています。
始める前に、Logto インスタンスが用意されていること、アプリケーションサーバーと Logto エンドポイント間でマシン間通信 (M2M) 接続が確立されていることを確認してください(Management API に必要です)。詳しくは Logto Management API をご覧ください。
ステップ 1: ワンタイムトークンのリクエスト
Logto Management API を使ってワンタイムトークンを作成します。
POST /api/one-time-tokens
リクエストボディの例:
{
"email": "[email protected]",
// 任意。デフォルトは 600(10 分)。
"expiresIn": 3600,
// 任意。検証に成功した場合、指定した組織にユーザーがプロビジョニングされます。
"context": {
"jitOrganizationIds": ["abcdefgh1234"]
}
}
ステップ 2: マジックリンクの作成
ワンタイムトークンを取得したら、マジックリンクを作成し、エンドユーザーのメールアドレスに送信できます。
マジックリンクには少なくともトークンとユーザーのメールアドレスをパラメーターとして含め、アプリケーション内のランディングページへ遷移させる必要があります。
例: https://yourapp.com/landing-page
マジックリンクの例:
https://yourapp.com/landing-page?token=YHwbXSXxQfL02IoxFqr1hGvkB13uTqcd&[email protected]
マジックリンク内のパラメーター名は完全にカスタマイズ可能です。 アプリケーションの要件に応じて追加情報を含めたり、すべての URL パラメーターをエンコードしたりできます。
ステップ 3: Logto SDK で認証 (Authentication) フローを開始
エンドユーザーがマジックリンクをクリックしてアプリケーションに遷移した後、URL から token
と email
パラメーターを抽出し、Logto SDK の signIn()
関数を呼び出して認証 (Authentication) フローを開始します。
// React の例
import { useLogto } from '@logto/react';
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
const TokenLandingPage = () => {
const { signIn } = useLogto();
const [searchParams] = useSearchParams();
useEffect(() => {
// マジックリンクからトークンとメールアドレスを抽出
const oneTimeToken = searchParams.get('token');
const email = searchParams.get('email');
// これはサインインリダイレクト URI の例です
const redirectUri = 'https://yourapp.com/callback';
if (oneTimeToken && email) {
signIn({
redirectUri,
clearTokens: false, // 任意。下記の警告メッセージを参照
extraParams: {
'one_time_token': oneTimeToken,
'login_hint': email,
},
});
}
}, [searchParams, signIn]);
return <>お待ちください...</>;
};
ユーザーがすでにサインインしている場合、SDK の signIn()
関数を呼び出すと、クライアントストレージからすべてのキャッシュされたトークン(ID トークン、アクセス トークン、リフレッシュ トークン)が自動的にクリアされ、
現在のユーザーの認証 (Authentication) 状態が失われます。
そのため、既存のトークンをクリアしないように追加のサインインパラメーター clearTokens: false
を指定してください。
これを指定した場合、サインインコールバックページで手動でトークンをクリアする必要があります。
マジックリンクが認証 (Authentication) 済みユーザー向けでない場合は、この注意事項は無視してください。
ステップ 4: (任意)サインインコールバックページでキャッシュされたトークンをクリア
サインイン関数で clearTokens: false
を指定した場合、サインインコールバックページで手動でトークンをクリアする必要があります。
// React の例
import { useHandleSignInCallback, useLogto } from '@logto/react';
import { useEffect } from 'react';
const Callback = () => {
const { clearAllTokens } = useLogto();
useEffect(() => {
void clearAllTokens();
}, [clearAllTokens]);
useHandleSignInCallback(() => {
// ホームページへ遷移
});
return <>お待ちください...</>;
};
よくある質問
マジックリンクで新しいユーザーを組織に招待できますか?
はい、マジックリンクを使ってアプリケーションや組織に新しいユーザーを招待できます。
組織に新しいユーザーを招待したい場合は、リクエストボディで jitOrganizationIds
を指定してください。
ユーザーは検証に成功すると自動的に組織に参加し、デフォルトの組織ロールが割り当てられます。 組織詳細ページの「ジャストインタイムプロビジョニング」セクションで、組織のデフォルトロールを設定できます。
ワンタイムトークンは有効期限がありますか?
はい、ワンタイムトークンは指定した expiresIn
時間(秒単位)で有効期限が切れます。デフォルトの有効期限は 10 分です。
「サインイン体験」でユーザー登録を無効にした場合でも、マジックリンクでユーザーを招待できますか?
はい、「サインイン体験」でユーザー登録を無効にしても、マジックリンクでユーザーを招待できます。
すでにサインインしているユーザーが、別のマジックリンクをクリックした場合はどうなりますか?
いくつかのシナリオが考えられます:
- ユーザーがすでにサインインしており、現在のユーザーアカウントに関連付けられたマジックリンクをクリックした場合。この場合、Logto はワンタイムトークンを検証し、必要に応じてユーザーを指定した組織にプロビジョニングします。
- ユーザーがすでにサインインしており、別のアカウントに関連付けられたマジックリンクをクリックした場合。この場合、Logto は新しいアカウントで続行するか、現在のアカウントでアプリケーションに戻るかをユーザーに促します。
- ユーザーが新しいアカウントで続行を選択した場合、トークン検証が成功すると Logto は新しいアカウントに切り替えます。
- ユーザーが現在のアカウントを維持することを選択した場合、Logto はトークンを検証せず、現在のアカウントでアプリケーションに戻ります。
- サインインプロンプトが "login" または "login" を含む場合、Logto は切り替えを促さず、ワンタイムトークンに関連付けられたアカウントで自動的にサインインします。