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ập | Giá trị |
|---|---|
| Bên phát hành | https://<handle>.usherid.com |
| URL khám phá | https://<handle>.usherid.com/.well-known/openid-configuration |
| Luồng | Mã ủy quyền (response_type=code) |
| PKCE | Bắt buộc, code_challenge_method=S256 |
| Phạm vi | openid profile email offline_access |
| Xác thực client | Theo 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.
curl -s https://acme.usherid.com/.well-known/openid-configuration | jq{
"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:
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:
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 |
|---|---|
| Python | Authlib |
| Go | coreos/go-oidc với golang.org/x/oauth2 |
| Java | Spring Security OAuth 2.0 Client |
| .NET | Microsoft.AspNetCore.Authentication.OpenIdConnect |
| Ruby | omniauth_openid_connect |
| PHP | jumbojett/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.