跳至內容

以開放標準,為你的 App 提供身分識別

引你入內。

一個帳號,通行每扇門。

Usher Identity 以 OpenID Connect 與 OAuth 2.1 讓使用者登入你的 App:通行密鑰、驗證碼、社群帳號登入與組織功能,而且每個環境都與其他環境完全隔離。

免費開始使用。也能在你自己的伺服器上執行。

Lobby

歡迎你,而不是盤問你的登入頁面。

Lobby 是 Usher Identity 為你的 App 代管的登入頁面。它一定會說明使用者要前往哪裡,而且不論是哪個 App 帶他們來,看起來都一樣,讓大家學會信任它。

即將前往
主題
  • 每一次都會指出你要前往的產品。
  • 通行密鑰、電子郵件驗證碼與魔術連結,只有在你需要時才提供密碼。
  • 無論淺色或深色,在每個產品中都是同樣從容的頁面。

這是可以實際操作的 Lobby 副本。它在這個頁面中執行,不會傳送任何資料,也不會讓任何人登入。

Usher IdentityUsher Identity即將前往 Acme Notes

歡迎回來。

使用你的 Usher Identity 帳號登入。

第一次來嗎?

由 Usher Identity 保護

採用標準,不被綁定

使用你的技術堆疊早已熟悉的通訊協定。

Usher Identity 首先是一個 OpenID Connect 提供者。合適的時候可以使用我們的 SDK,也可以用任何語言的任何 OIDC 程式庫。即使有一天你離開,你的 App 也不必改變讓使用者登入的方式。

內含重新整理權杖、同意與範圍。
  • OIDC Core · Discovery

    OpenID Connect

    每個環境都有自己的探索文件、ID 權杖和 userinfo。任何經過認證的用戶端程式庫都能使用。

  • 僅限 S256

    OAuth 2.1 與 PKCE

    每個用戶端(不論公開或機密)都使用搭配 PKCE 的授權碼流程。沒有隱含流程,權杖端點也不接受密碼。

  • RS256 · ES256 · EdDSA

    JWKS 與金鑰輪替

    每個環境都以自己的金鑰簽署,並發布在它的 jwks_uri。輪替金鑰時,已登入的使用者不受影響。

  • RFC 7662 · RFC 7009

    內省與撤銷

    查詢權杖是否仍然有效,或立即終止它。Usher Identity 每次請求都會檢查自己的工作階段,因此終止後立即生效。

  • RP 發起登出與後端通道登出

    從你的 App 登出,或讓 Usher Identity 在任何地方的工作階段結束時通知每個 App。

  • RFC 9449

    DPoP

    將權杖綁定到用戶端持有的金鑰,因此被竊取的權杖單獨拿到也沒有用。

  • WebAuthn

    通行密鑰

    從一開始就內建,而不是附加功能。使用者用指紋、臉孔或安全密鑰登入,也就無從被網路釣魚。

  • TOTP

    驗證器 App

    任何驗證器產生的時間型驗證碼,並提供備用碼。雙重認證可設為選用或必要。

  • 魔術連結

    在收件匣點一下就好。有效時間短、只能使用一次,而且綁定寄出它的環境。

  • 電子郵件驗證碼

    六位數字,適合在一部裝置上登入、在另一部裝置上看郵件的人。

  • 社群帳號登入

    Google、GitHub、Microsoft 和 Apple。只有在帳號的電子郵件經過證實後,才會連結帳號。

  • 組織與團隊

    為使用你 App 的企業提供成員、角色與邀請功能。

  • 即將推出

    SAML

    與你客戶的企業員工身分提供者進行單一登入。

  • 即將推出

    SCIM

    從你客戶的目錄佈建與取消佈建帳號。

登入的運作方式

五個步驟,每一步都符合標準。

這是 OpenID Connect 搭配 PKCE 的授權碼流程,也是每個正規的身分提供者都使用的流程。往下捲動來看看。

  1. 01

    你的 App 將使用者送往 Lobby。

    當有人選擇「使用 Usher Identity 繼續」時,你的 App 會將他們重新導向到你環境的授權端點,並附上 PKCE 挑戰值,以及一個稍後要檢查的 state 值。

    GET acme.usherid.com/api/auth/oauth2/authorize
      ?response_type=code
      &client_id=acme_web
      &redirect_uri=https://app.acme.example/callback
      &scope=openid profile email offline_access
      &state=k3Jx…
      &code_challenge=E9Mel…cM
      &code_challenge_method=S256
  2. 02

    他們用自己的方式登入。

    通行密鑰、電子郵件驗證碼、魔術連結、社群帳號或密碼:Lobby 只提供你的環境允許的方式,而且一定會說明他們要前往哪個 App。

    Usher IdentityUsher Identity即將前往 Acme

    歡迎回來。

    使用通行密鑰
    用電子郵件寄驗證碼給我
  3. 03

    他們同意分享。

    第一次時,使用者會看到你的 App 要求哪些資訊(他們的個人資料、電子郵件、保持登入),並且只需同意一次。

    Acme 想要:

    • 查看你的姓名和照片
    • 查看你的電子郵件地址
    • 讓你保持登入
    取消允許
  4. 04

    Usher Identity 交回一組授權碼。

    瀏覽器會回到你的重新導向 URI,帶著一組有效五分鐘、只能使用一次的授權碼,以及你送出的 state,由你的 App 加以檢查。

    302 Found
    Location: https://app.acme.example/callback
      ?code=SplxlOBeZQQYbYS6WxSbIA
      &state=k3Jx…
  5. 05

    你的 App 用它換取權杖。

    你的伺服器將授權碼和 PKCE 驗證器傳送到權杖端點。回傳的是說明使用者身分的 ID 權杖、用於你 API 的存取權杖,以及用來保持登入的重新整理權杖。

    POST acme.usherid.com/api/auth/oauth2/token
      grant_type=authorization_code&code=Splx…
      &code_verifier=dBjftJeZ4CVP…
    
    {
      "token_type": "Bearer",
      "access_token": "eyJhbGciOiJSUzI1NiIs…",
      "id_token": "eyJhbGciOiJSUzI1NiIs…",
      "refresh_token": "8xLOxBtZp8…",
      "expires_in": 600
    }

從設計上隔離

每個環境都是一棟獨立的建築。

你的正式環境和開發環境,以及其他每位客戶的環境,都沒有共用任何重要的東西。一個環境出了錯,也無法讀取另一個環境、替它簽署,或登入它。

自己的 Postgres schema
不是共用資料表中的租戶欄位,而是專為該環境建立的 schema,裡面沒有任何其他東西。
自己的簽署金鑰
一個環境的權杖,永遠無法通過另一個環境金鑰的驗證。
自己的密封機密
以環境自己的資料金鑰密封,而這把資料金鑰本身又由主金鑰包裹。
自己的主機
簽發者位於與 Usher 網站和 Console 不同的網域,並使用僅限主機的 Cookie。

usheridentity.com

網站、Usher Identity Console、Usher Identity 帳號

*.usherid.com

每個環境一個簽發者,位於獨立的網域

環境

使用者、工作階段和權杖都存放在專為這個環境建立的 schema 中。查詢只會針對該 schema 執行,絕不會使用帶有租戶欄位的共用資料表。

把 Acme 正式環境中密封的 Google 用戶端機密,複製到 Northwind 正式環境。

給開發者

你的第一次登入,三種方式。

SDK 推出後可以直接加入,也可以使用你已經信任的 OIDC 程式庫,或從閱讀探索文件開始。底層都是同一套通訊協定。

app/layout.tsx · app/page.tsx隨 SDK 推出
// app/layout.tsx
import { UsherProvider } from '@usher/nextjs'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <UsherProvider>{children}</UsherProvider>
      </body>
    </html>
  )
}

// app/page.tsx
import { SignIn, UserButton, currentUser } from '@usher/nextjs'

export default async function Page() {
  const user = await currentUser()
  return user ? <UserButton /> : <SignIn />
}

自行架設

你的伺服器,你的金鑰。

你可以將 Usher Identity 當作服務使用,也可以在自己的伺服器上,用自己的金鑰和自己的資料庫執行同一個平台。

  • Docker

    一個 Compose 檔案:包含各個 App、Postgres、Valkey、Caddy 邊緣伺服器和對外連線代理。容器執行時不得取得新權限,並捨棄了 capabilities。

  • Ubuntu

    一台普通的 Ubuntu 伺服器就夠了。Caddy 負責終止 TLS,機密則以檔案形式交給容器,絕不會寫進映像檔。

  • Postgres

    所有資料都存放在 Postgres 中,每個環境一個 schema。它和 Valkey 位於一個沒有路由能通往網際網路的網路上。

在 Usher Identity 的程式碼簽出目錄中
# on an Ubuntu server with Docker Engine and the Compose plugin
bash infra/scripts/setup-env.sh --prod \
  --domain usher.example --tenant-domain usherid.example

docker compose -f compose.yaml -f compose.prod.yaml \
  --profile core --profile apps --profile edge up -d --wait

pnpm db:migrate   # applies the database migrations

完整的自行架設指南即將推出。上面的指令就是它的大致樣貌。

帶你的使用者入內。

建立工作區和專案,你的第一個環境就會附帶專屬的簽發者、金鑰和 Lobby。

登入一次,處處受歡迎。