Chuyển đến nội dung
Tài liệu · Thư viện OIDC bất kỳ

Bắt đầu nhanh: thư viện OIDC bất kỳ

Usher là một nhà cung cấp OpenID Connect chuẩn. Nếu ngôn ngữ của bạn có một client OIDC đã được chứng nhận, bạn đã có đủ mọi thứ cần thiết: hãy trỏ client đến tài liệu khám phá của môi trường và dùng luồng mã ủy quyền với PKCE.

Các thiết lập

Thiết lậpGiá trị
Bên phát hànhhttps://<handle>.usherid.com
URL khám pháhttps://<handle>.usherid.com/.well-known/openid-configuration
LuồngMã ủy quyền (response_type=code)
PKCEBắt buộc, code_challenge_method=S256
Phạm viopenid profile email offline_access
Xác thực clientTheo danh sách trong token_endpoint_auth_methods_supported

Tên định danh của môi trường nằm trong Usher Console, bên cạnh bên phát hành của nó. Môi trường phát triển nhận một tên định danh ngẫu nhiên, chẳng hạn wise-otter-42; môi trường chính thức có tên định danh bạn đã chọn. Một môi trường chính thức cũng có thể nằm ở tên miền riêng của bạn, chẳng hạn login.acme.com: khi đó, đó là bên phát hành của nó, sau khi bạn đã trỏ tên miền đến Usher bằng một bản ghi CNAME.

Đọc tài liệu khám phá

Mọi endpoint và khóa mà client của bạn cần đều được liệt kê ở đây. Hãy để thư viện đọc tài liệu này thay vì sao chép URL vào mã của bạn.

Terminal
curl -s https://acme.usherid.com/.well-known/openid-configuration | jq
Phản hồi (rút gọn)
{
  "issuer": "https://acme.usherid.com",
  "authorization_endpoint": "https://acme.usherid.com/api/auth/oauth2/authorize",
  "token_endpoint": "https://acme.usherid.com/api/auth/oauth2/token",
  "userinfo_endpoint": "https://acme.usherid.com/api/auth/oauth2/userinfo",
  "jwks_uri": "https://acme.usherid.com/api/auth/jwks",
  "introspection_endpoint": "https://acme.usherid.com/api/auth/oauth2/introspect",
  "revocation_endpoint": "https://acme.usherid.com/api/auth/oauth2/revoke",
  "end_session_endpoint": "https://acme.usherid.com/api/auth/oauth2/end-session",
  "scopes_supported": ["openid", "profile", "email", "offline_access"],
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token", "client_credentials"],
  "code_challenge_methods_supported": ["S256"]
}

Luồng

Đưa người dùng đến endpoint ủy quyền

Tạo một PKCE verifier ngẫu nhiên và lưu lại, cùng một state ngẫu nhiên, ở nơi chỉ phiên của trình duyệt này truy cập được (một cookie httpOnly, ngắn hạn là lựa chọn tốt). Sau đó chuyển hướng với response_type=code, client_id và redirect_uri của bạn, các phạm vi ở trên, state, và code_challenge S256 của verifier.

Để họ đăng nhập

Từ đây Lobby sẽ lo phần còn lại: Lobby nêu tên ứng dụng của bạn, đưa ra các cách đăng nhập mà môi trường cho phép, và xin sự đồng ý trong lần đầu tiên.

Kiểm tra callback

Usher chuyển hướng đến redirect_uri của bạn kèm code và state. Hãy từ chối phản hồi trừ khi state khớp với giá trị bạn đã lưu. Mã chỉ dùng một lần và có hiệu lực năm phút.

Đổi mã lấy token

Từ máy chủ của bạn, gửi mã và PKCE verifier đến endpoint token:

Yêu cầu token
curl -s -X POST https://acme.usherid.com/api/auth/oauth2/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=authorization_code \
-d code="$CODE" \
-d redirect_uri=https://app.acme.example/callback \
-d code_verifier="$CODE_VERIFIER"

Xác thực token ID

Kiểm tra chữ ký của token bằng các khóa tại jwks_uri, và kiểm tra rằng iss là bên phát hành của bạn, aud là Client ID của bạn và exp ở trong tương lai. Thư viện của bạn làm việc này giúp bạn; hãy chắc chắn rằng tính năng này không bị tắt.

Trong Node.js

openid-client làm tất cả những điều trên, kể cả xác thực:

openid-client
import * as client from 'openid-client'

// discovery: every endpoint and key comes from the issuer
const config = await client.discovery(
  new URL('https://acme.usherid.com'),
  process.env.USHER_CLIENT_ID!,
  process.env.USHER_CLIENT_SECRET!,
)

// 1. send them to the Lobby, with PKCE (S256) and a state to check later
const codeVerifier = client.randomPKCECodeVerifier()
const state = client.randomState()
const url = client.buildAuthorizationUrl(config, {
  redirect_uri: 'https://app.acme.example/callback',
  scope: 'openid profile email offline_access',
  code_challenge: await client.calculatePKCECodeChallenge(codeVerifier),
  code_challenge_method: 'S256',
  state,
})
// keep codeVerifier and state in a short-lived httpOnly cookie, then redirect to url

// 2. back at /callback: swap the code for tokens
const tokens = await client.authorizationCodeGrant(config, new URL(request.url), {
  pkceCodeVerifier: codeVerifier,
  expectedState: state,
})
const { sub, email, name } = tokens.claims()!

Trong các ngôn ngữ khác

Các thư viện phổ biến này đều dùng OpenID Connect chuẩn và hoạt động với Usher mà không cần gì riêng cho Usher:

Ngôn ngữThư viện
PythonAuthlib
Gocoreos/go-oidc với golang.org/x/oauth2
JavaSpring Security OAuth 2.0 Client
.NETMicrosoft.AspNetCore.Authentication.OpenIdConnect
Rubyomniauth_openid_connect
PHPjumbojett/openid-connect-php

Duy trì đăng nhập

Với phạm vi offline_access, phản hồi token sẽ kèm một token làm mới. Hãy dùng nó với grant_type=refresh_token để lấy token truy cập mới khi token cũ hết hạn. Token làm mới được xoay vòng: mỗi lần dùng sẽ trả về một token mới, và token cũ ngừng hoạt động.

Đăng xuất

Trước tiên, hãy xóa phiên của riêng bạn, rồi chuyển hướng đến end_session_endpoint kèm post_logout_redirect_uri (và id_token_hint nếu có), để Lobby cũng quên người dùng.