เริ่มต้นอย่างรวดเร็ว: ไลบรารี OIDC ใดก็ได้
Usher เป็นผู้ให้บริการ OpenID Connect มาตรฐาน หากภาษาของคุณมีไคลเอ็นต์ OIDC ที่ได้รับการรับรอง คุณก็มีทุกอย่างที่ต้องใช้แล้ว เพียงชี้ไคลเอ็นต์ไปที่เอกสาร Discovery ของสภาพแวดล้อม แล้วใช้โฟลว์รหัสการอนุญาตพร้อม PKCE
การตั้งค่า
| การตั้งค่า | ค่า |
|---|---|
| Issuer | https://<handle>.usherid.com |
| URL ของ Discovery | https://<handle>.usherid.com/.well-known/openid-configuration |
| โฟลว์ | รหัสการอนุญาต (response_type=code) |
| PKCE | จำเป็น ใช้ code_challenge_method=S256 |
| ขอบเขต | openid profile email offline_access |
| การยืนยันตัวตนของไคลเอ็นต์ | ตามที่ระบุไว้ใน token_endpoint_auth_methods_supported |
แฮนเดิลของสภาพแวดล้อมอยู่ใน Usher Console ข้างๆ Issuer สภาพแวดล้อมพัฒนาได้แฮนเดิลแบบสุ่ม เช่น wise-otter-42 ส่วนสภาพแวดล้อมใช้งานจริงมีแฮนเดิลที่คุณเลือก สภาพแวดล้อมใช้งานจริงยังอยู่ที่โดเมนของคุณเองแทนได้ เช่น login.acme.com เมื่อคุณชี้โดเมนมาที่ Usher ด้วยระเบียน CNAME แล้ว โดเมนนั้นจะเป็น Issuer ของสภาพแวดล้อม
อ่านเอกสาร Discovery
ทุกเอนด์พอยต์และคีย์ที่ไคลเอ็นต์ของคุณต้องใช้มีอยู่ในเอกสารนี้ ให้ไลบรารีของคุณอ่านเอกสารนี้ แทนการคัดลอก URL ลงในโค้ด
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"]
}โฟลว์
ส่งผู้ใช้ไปยังเอนด์พอยต์การอนุญาต
สร้าง PKCE verifier แบบสุ่มแล้วเก็บไว้พร้อม state แบบสุ่ม ในที่ที่มีเพียงเซสชันของเบราว์เซอร์นี้เข้าถึงได้ (คุกกี้อายุสั้นแบบ httpOnly ใช้ได้ดี) จากนั้นเปลี่ยนเส้นทางพร้อม response_type=code, client_id และ redirect_uri ของคุณ ขอบเขตด้านบน state และ code_challenge แบบ S256 ของ verifier
ให้ผู้ใช้ลงชื่อเข้า
จากนี้ Lobby จะรับช่วงต่อ: บอกชื่อแอปของคุณ เสนอวิธีลงชื่อเข้าที่สภาพแวดล้อมของคุณอนุญาต และขอความยินยอมในครั้งแรก
ตรวจสอบ Callback
Usher เปลี่ยนเส้นทางไปยัง redirect_uri ของคุณพร้อม code และ state ให้ปฏิเสธการตอบกลับ เว้นแต่ state จะตรงกับค่าที่คุณเก็บไว้ รหัสใช้ได้ครั้งเดียวและมีอายุห้านาที
แลกรหัสเป็นโทเค็น
จากเซิร์ฟเวอร์ของคุณ ให้ส่งรหัสและ PKCE verifier ไปยังเอนด์พอยต์โทเค็นด้วย POST:
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"ตรวจสอบโทเค็น ID
ตรวจสอบลายเซ็นของโทเค็นกับคีย์ที่ jwks_uri และตรวจสอบว่า iss คือ Issuer ของคุณ aud คือ Client ID ของคุณ และ exp ยังไม่ถึง ไลบรารีของคุณทำสิ่งนี้ให้ เพียงตรวจดูให้แน่ใจว่าไม่ได้ปิดไว้
ใน Node.js
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()!ในภาษาอื่น
ไลบรารีที่ใช้กันแพร่หลายเหล่านี้ล้วนใช้ OpenID Connect มาตรฐาน และทำงานกับ Usher ได้โดยไม่ต้องมีสิ่งใดเฉพาะสำหรับ Usher:
| ภาษา | ไลบรารี |
|---|---|
| Python | Authlib |
| Go | coreos/go-oidc ร่วมกับ 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 |
การลงชื่อเข้าค้างไว้
เมื่อใช้ขอบเขต offline_access การตอบกลับโทเค็นจะมีโทเค็นรีเฟรชด้วย ใช้โทเค็นรีเฟรชกับ grant_type=refresh_token เพื่อขอโทเค็นการเข้าถึงใหม่เมื่อโทเค็นเดิมหมดอายุ โทเค็นรีเฟรชจะหมุนเวียน: การใช้แต่ละครั้งจะได้โทเค็นใหม่ และโทเค็นเดิมจะใช้ไม่ได้อีก
การลงชื่อออก
ล้างเซสชันของคุณเองก่อน แล้วเปลี่ยนเส้นทางไปยัง end_session_endpoint พร้อม post_logout_redirect_uri (และ id_token_hint หากมี) เพื่อให้ Lobby ลืมผู้ใช้ด้วย