ข้ามไปยังเนื้อหา
เอกสาร · ไลบรารี OIDC ใดก็ได้

เริ่มต้นอย่างรวดเร็ว: ไลบรารี OIDC ใดก็ได้

Usher เป็นผู้ให้บริการ OpenID Connect มาตรฐาน หากภาษาของคุณมีไคลเอ็นต์ OIDC ที่ได้รับการรับรอง คุณก็มีทุกอย่างที่ต้องใช้แล้ว เพียงชี้ไคลเอ็นต์ไปที่เอกสาร Discovery ของสภาพแวดล้อม แล้วใช้โฟลว์รหัสการอนุญาตพร้อม PKCE

การตั้งค่า

การตั้งค่าค่า
Issuerhttps://<handle>.usherid.com
URL ของ Discoveryhttps://<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 ทำทุกอย่างข้างต้นให้ รวมถึงการตรวจสอบความถูกต้อง:

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:

ภาษาไลบรารี
PythonAuthlib
Gocoreos/go-oidc ร่วมกับ golang.org/x/oauth2
JavaSpring Security OAuth 2.0 Client
.NETMicrosoft.AspNetCore.Authentication.OpenIdConnect
Rubyomniauth_openid_connect
PHPjumbojett/openid-connect-php

การลงชื่อเข้าค้างไว้

เมื่อใช้ขอบเขต offline_access การตอบกลับโทเค็นจะมีโทเค็นรีเฟรชด้วย ใช้โทเค็นรีเฟรชกับ grant_type=refresh_token เพื่อขอโทเค็นการเข้าถึงใหม่เมื่อโทเค็นเดิมหมดอายุ โทเค็นรีเฟรชจะหมุนเวียน: การใช้แต่ละครั้งจะได้โทเค็นใหม่ และโทเค็นเดิมจะใช้ไม่ได้อีก

การลงชื่อออก

ล้างเซสชันของคุณเองก่อน แล้วเปลี่ยนเส้นทางไปยัง end_session_endpoint พร้อม post_logout_redirect_uri (และ id_token_hint หากมี) เพื่อให้ Lobby ลืมผู้ใช้ด้วย