魔術連結(一次性權杖)
類似一次性密碼(OTP),一次性權杖(one-time token)是另一種無密碼驗證 (Authentication) 方法,可用於驗證使用者身分。該權杖僅在有限時間內有效,並與終端使用者的電子郵件地址綁定。
有時你可能希望邀請新使用者加入你的應用程式 / 組織,而不需他們先建立帳號;或是你忘記密碼,想透過電子郵件快速驗證身分來登入 / 重設密碼。在這些情境下,應用程式可以將「魔術連結」發送到你的電子郵件信箱,當你點擊該連結時即會立即完成驗證 (Authentication)。
應用程式開發者可以利用一次性權杖組成魔術連結,並將其發送到終端使用者的電子郵件地址。
使用情境
Logto 支援以下魔術連結應用場景:
- 僅限邀請註冊:針對內部工具或測試階段的 AI 產品,你可以停用公開註冊,僅透過魔術連結邀請特定使用者。
- 組織成員邀請:SaaS 產品可利用魔術連結邀請新成員加入組織,簡化導入流程。
- 登入 / 註冊:透過電子郵件發送魔術連結,實現無密碼登入或註冊。
例如,當你停用公開註冊時,可以將包含一次性權杖的魔術連結(如 https://yourapp.com/landing-page?token=YHwbXSXxQfL02IoxFqr1hGvkB13uTqcd&email=user@example.com)發送到使用者信箱,邀請其完成帳號建立。你可以在自有郵件發送服務中自訂郵件模板,例如:
目前不支援:
- 使用魔術連結重設密碼。
- 以手機號碼或使用者名稱作為識別標識。
一次性權杖流程
以下為使用一次性權杖進行驗證 (Authentication) 的時序圖:
實作指南
Logto 提供一組 Management API 與 Experience API,協助你輕鬆實作魔術連結。
開始前,請確保你已準備好 Logto 實例,並已在應用程式伺服器與 Logto 端點間建立機器對機器連線(Management API 需要)。詳情請參閱 Logto Management API。
步驟 1:請求一次性權杖
使用 Logto Management API 建立一次性權杖。
POST /api/one-time-tokens
請求範例:
{
"email": "user@example.com",
// 可選。預設 600 秒(10 分鐘)。
"expiresIn": 3600,
// 可選。驗證成功後,使用者將被佈建到指定組織。
"context": {
"jitOrganizationIds": ["abcdefgh1234"]
}
}
步驟 2:組成你的魔術連結
取得一次性權杖後,你可以組成魔術連結並發送到終端使用者的電子郵件信箱。魔術連結至少應包含權杖與使用者電子郵件作為參數,並導向你應用程式的著陸頁,例如 https://yourapp.com/landing-page。
魔術連結範例:
https://yourapp.com/landing-page?token=YHwbXSXxQfL02IoxFqr1hGvkB13uTqcd&email=user@example.com
魔術連結中的參數名稱可完全自訂。你可根據應用需求新增額外資訊,並對所有 URL 參數進行編碼。
步驟 3:透過 Logto SDK 觸發驗證 (Authentication) 流程
終端使用者點擊魔術連結並進入你的應用程式後,你可以從 URL 擷取 token 與 email 參數,然後呼叫 Logto SDK 的 signIn() 函式以觸發驗證流程。
// 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 權杖、存取權杖、重新整理權杖),導致目前使用者的驗證狀態遺失。
因此,你應額外指定登入參數 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。
使用者驗證成功後會自動加入組織,並分配預設組織角色。請至組織詳細頁的「即時佈建 (Just-in-time provisioning)」區段設定組織的預設角色。
我可以用魔術連結將使用者分配到特定角色嗎?
魔術連結驗證 (Authentication) 流程不支援直接分配角色給使用者。但你可以在使用者註冊後,透過 Webhook 與 Management API 更新使用者角色。
一次性權杖會過期嗎?
會,一次性權杖會在指定的 expiresIn 時間(秒)後過期。預設有效時間為 10 分鐘。
如果我在「登入體驗 (Sign-in Experience)」中停用使用者註冊,還能用魔術連結邀請使用者嗎?
可以,即使你在「登入體驗 (Sign-in Experience)」中停用使用者註冊,仍可使用魔術連結邀請使用者。
若使用者已登入,然後又點擊另一個魔術連結會發生什麼事?
可能出現以下幾種情境:
- 使用者已登入,點擊與目前帳號關聯的魔術連結。此時 Logto 仍會驗證一次性權杖,並視需要將使用者佈建到指定組織。
- 使用者已登入,點擊與不同帳號關聯的魔術連結。此時 Logto 會提示使用者切換至新帳號,或以目前帳號返回應用程式。
- 若使用者選擇切換至新帳號,Logto 會在權杖驗證成功後切換帳號。
- 若使用者選擇維持目前帳號,Logto 不會驗證權杖,並以目前帳號返回應用程式。
- 若你的登入提示設為 "login" 或包含 "login",Logto 會自動以一次性權杖關聯的帳號登入,不會提示切換。這是因為 "login" 提示表示明確的驗證 (Authentication) 意圖,優先於現有會話。