الانتقال إلى المحتوى
الوثائق · أي مكتبة OIDC

بدء سريع: أي مكتبة OIDC

يُعد Usher مزوّد OpenID Connect قياسيًا. إذا كانت للغتك مكتبة عميل OIDC معتمدة، فلديك بالفعل كل ما تحتاجه: وجّهها إلى مستند الاكتشاف الخاص ببيئتك، واستخدم تدفق رمز التفويض مع PKCE.

الإعدادات

الإعدادالقيمة
جهة الإصدارhttps://<handle>.usherid.com
عنوان URL للاكتشاف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، بجانب جهة إصدارها. تحصل بيئات التطوير على اسم عشوائي، مثل wise-otter-42، أما بيئات الإنتاج فلها الاسم الذي اخترته. ويمكن لبيئة الإنتاج أن تقع على نطاقك الخاص بدلًا من ذلك، مثل login.acme.com، وعندها يكون هذا النطاق جهة إصدارها، بعد أن توجّهه إلى Usher بسجل CNAME.

اقرأ مستند الاكتشاف

كل نقطة نهاية ومفتاح يحتاجه عميلك مُدرج هنا. دع مكتبتك تقرأه بدلًا من نسخ عناوين 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 عشوائيًا واحفظه، مع قيمة state عشوائية، في مكان لا تصل إليه إلا جلسة هذا المتصفح (يفي ملف تعريف ارتباط قصير العمر من نوع httpOnly بالغرض). ثم أعد التوجيه مع response_type=code، و client_id و redirect_uri الخاصين بك، والنطاقات أعلاه، وقيمة state، و code_challenge المحسوب بطريقة S256 من المُحقِّق.

دعه يسجّل الدخول

يتولى Lobby الأمر من هنا: يذكر اسم تطبيقك، ويعرض طرق تسجيل الدخول التي تسمح بها بيئتك، ويطلب الموافقة في المرة الأولى.

تحقق من رد الاستدعاء

يعيد Usher التوجيه إلى redirect_uri الخاص بك مع code و state. ارفض الاستجابة ما لم تطابق state القيمة التي حفظتها. الرمز يُستخدم مرة واحدة ويبقى صالحًا خمس دقائق.

استبدل الرمز برموز مميزة

من خادمك، أرسل الرمز ومُحقِّق PKCE إلى نقطة نهاية الرموز المميزة:

طلب الرمز المميز
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"

تحقق من صحة رمز الهوية

تحقق من توقيعه مقابل المفاتيح الموجودة على jwks_uri، ومن أن iss هي جهة إصدارك، و aud هو معرّف العميل الخاص بك، و 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 دون أي شيء خاص به:

اللغةالمكتبة
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 الشخص أيضًا.