權杖與使用者資訊 開發人員
上次更新:2026年8月15日
權杖與使用者資訊
本文介紹如何在成功換取權杖後校驗 ID Token、使用 Access Token,以及讀取 UserInfo 返回的聲明。
權杖類型
| 權杖 | 形態(入口網站應用程式) | 用途 |
|---|---|---|
id_token | JWT,ES256 簽章 | 向用戶端證明使用者已認證;內含 pairwise sub 等 |
access_token | JWT,ES256 簽章 | 呼叫 UserInfo 等受保護資源;可用 JWKS 驗簽 |
refresh_token | 不透明權杖(僅機密用戶端) | 重新整理 Access Token |
探索文件中的 id_token_signing_alg_values_supported 應包含 ES256。用於驗簽的公開金鑰可從以下端點取得:
GET {ISSUER}/oauth2/jwks
建議快取 JWKS,並根據 kid 選擇金鑰;發生金鑰輪換時,請重新取得 JWKS。
ID Token 校驗(必做)
至少校驗:
- 簽章:ES256 + JWKS。
iss:等於你的 Issuer(如https://api-passport.swaymoon.com)。aud:包含你的client_id。exp/iat:權杖未過期,並為時鐘偏差保留合理的容差。nonce(若你在授權請求中傳送了):與工作階段中保存的值一致。
ID Token 中的 sub 是面向你的應用程式(團隊)的穩定使用者識別。應用程式方應使用該欄位作為關聯本機使用者的主鍵。
目前實作下,email 與多數資料類聲明以 UserInfo 為準;請勿假設 ID Token 內一定含有 email 或 picture。例外:已授予 locale 時,ID Token 會包含 locale(BCP 47,如 zh-CN / zh-TW / en / ja),授權回呼即可讀取使用者首選語言。校驗完 ID Token 的 sub 後,用 Access Token 呼叫 UserInfo 讀取其餘聲明。
Pairwise sub
通行帳戶對已綁定開發者團隊的用戶端使用 pairwise 主體識別:
- 同一自然人使用者多次登入你的團隊下的應用程式時,
sub保持相同。 - 同一使用者向另一團隊的應用程式授權時,
sub不同。 - 因此,不要假設可以透過
sub關聯不同應用程式或團隊中的使用者,也不要使用電子郵件替代sub作為唯一主鍵,因為使用者可能更換綁定電子郵件。
UserInfo
GET /userinfo
Host: api-passport.swaymoon.com
Authorization: Bearer ACCESS_TOKEN
該端點返回 JSON 格式的聲明。其中,sub 與 ID Token 中的值一致(pairwise)。
始終包含
| 聲明 | 含義 |
|---|---|
sub | pairwise 使用者識別(只要有 openid) |
資料聲明:分項授權 + 預設值
下列聲明始終出現在 UserInfo 回應中(欄位形狀穩定)。是否為真實使用者資料,取決於權杖 scope 是否包含對應細項(見《權限與同意》)。
| 聲明 | 所需 scope | 已授權時 | 未授權時(預設值) |
|---|---|---|---|
name | name | 顯示名稱 | 搖月使用者 |
nickname | nickname | 暱稱;未設定則為 搖月使用者 | 搖月使用者 |
picture | picture | 大頭貼 HTTPS URL;未設定則為空字串 | "" |
biography | biography | 個性簽名;未設定則為空字串 | "" |
gender | gender | male / female / other;未設定則為空字串 | "" |
birthdate | birthdate | YYYY-MM-DD;未設定則為空字串 | "" |
region | region | 地區代碼;未設定則為空字串 | "" |
preferred_username | preferred_username | 使用者名稱;未設定則為空字串 | "" |
locale | locale | BCP 47 標籤(zh-CN / zh-TW / en / ja) | "" |
updated_at | 任一資料細項 | 資料更新時間(Unix 秒) | 0 |
不要把預設值當成使用者真實資料。請結合權杖中的 scope 判斷哪些欄位已獲授權;未出現在 scope 中的資料項僅為佔位。
舊權杖若仍含整包 profile,伺服器端視為上述全部資料細項均已授權。
picture(大頭貼)
已授予 picture 且使用者已設定大頭貼時,UserInfo 返回絕對 HTTPS URL(Issuer 網域,例如 https://api-passport.swaymoon.com/media/avatars/…),可直接在瀏覽器或伺服器端拉取,無需額外鑑權。未設定大頭貼時為空字串。
接入方落庫時可二選一(或依產品需要組合):
- 只存連結:把
pictureURL 寫入本機使用者資料,展示時直接引用通行帳戶提供的位址。無需自建物件儲存或圖床;實作簡單。注意:使用者日後更換大頭貼後,舊 URL 可能失效(檔名含隨機段),宜在登入/重新整理資料時更新本機保存的連結,或展示前再讀一次 UserInfo。 - 存大頭貼檔案:用你方伺服器端(或安全的用戶端)GET 該 HTTPS URL,下載圖片後寫入自有儲存,本機只保留你方資源位址。適合希望圖片長期由己方 CDN 託管、或需離線/裁剪處理的場景。請遵守合理快取與體積限制,勿高頻重複拉取。
兩種方式都依賴正式環境 Issuer 為 HTTPS;本機聯調若 Issuer 為 http://…,返回的也可能是 HTTP,上線前請按正式設定驗證。
email
僅當權杖包含 email 時返回:
| 聲明 | 含義 |
|---|---|
email | 可用於聯絡該使用者的電子郵件位址(已驗證) |
email_verified | true(在返回電子郵件時) |
未授予 email 時,回應中不會包含上述電子郵件聲明(與資料預設值策略不同)。
使用者在同意頁可以選擇用普通電子郵件或隱私郵件把電子郵件權限授給你方:
| 使用者選擇 | 你方收到的 email | 真實電子郵件 |
|---|---|---|
| 普通電子郵件 | 使用者帳戶綁定的電子郵件 | 即該位址 |
| 隱私郵件 | 專用於你方應用程式的中繼位址(…@privaterelay.swaymoon.com) | 不會透過 UserInfo 或其他 OAuth 通道提供給你方;寄往該中繼位址的郵件會由通行帳戶轉發至使用者真實電子郵件 |
兩種情況下,email 都是可正常收信的位址,請按普通電子郵件處理(註冊建檔、發信、展示即可)。請了解使用者可能選擇隱私郵件,因此不要假設該位址一定是使用者的私人常用電子郵件,也不要嘗試索取或推斷真實位址。帳號主鍵請仍使用 sub。
需要電子郵件才能完成授權: 授權請求含 email,且使用者勾選/必選授予該權限時,若帳戶尚未綁定電子郵件,通行帳戶會先引導使用者綁定並驗證,成功後再繼續同意與發碼。因此權杖帶有 email scope 時,UserInfo 應始終包含 email 與 email_verified。使用者也可取消選用的 email 後繼續(若你方未將其設為必選)。
撤銷與內省
- 撤銷:
POST {ISSUER}/oauth2/revoke(按照 RFC 7009 和伺服器實作傳入權杖)。 - 內省:
POST {ISSUER}/oauth2/introspect(機密用戶端可查詢權杖狀態)。
具體參數以探索文件與伺服器回應為準。
建檔建議
- 用校驗後的
sub查找或建立本機使用者。 - 按權杖
scope解釋資料欄位;將未授權欄位的預設值視為「不可用」,不要寫入業務檔案。 - 大頭貼:優先決定「只存 HTTPS 連結」還是「下載後自建儲存」,見上文
picture。 - 機密用戶端須妥善保存
client_secret;非機密用戶端無金鑰。不要嘗試收集或儲存使用者的通行帳戶密碼。 - Access Token 的有效期較短,請按需重新整理;使用者登出時,可根據產品需要撤銷 Refresh Token。
下一步:閱讀《權限與同意》;如在接入過程中遇到問題,請參閱《範例與疑難排解》。