اربط أي تطبيق عبر OAuth/OIDC القياسي.
لا يعتمد OpenProof على لغة برمجة عند حدود البروتوكول. استخدم حزم SDK المرفقة حيث تكون مفيدة، أو تكامل من أي لغة تدعم HTTPS وOAuth 2.0/OpenID Connect.
نموذج التكامل
Your app ↓ redirect OpenProof /oauth/authorize ↓ authentication / provider / passkey / wallet ↓ your callback?code=...&state=...&iss=... ↓ code + verifier OpenProof /oauth/token ↓ access_token + id_token + optional refresh_token
استخدم رموز OAuth/OIDC لتكامل المنتج. ملف تعريف ارتباط جلسة OpenProof الآمن يخص أصل حساب/إدارة OpenProof ولا ينبغي نسخه إلى نطاق منتجك.
ابدأ بـ Discovery
https://auth.example.com/.well-known/openid-configuration https://auth.example.com/.well-known/jwks.json
يُعد Discovery الطريقة المفضلة للعملاء القابلين لإعادة الاستخدام لاكتشاف نقاط authorization وtoken وUserInfo وintrospection وبقية نقاط البروتوكول ذات الصلة.
سجّل منتجك
يمكن لمالك نشط بمستوى IAL2 استخدام /admin/console أو API الإدارة.
أنشئ application
curl --fail-with-body -b owner.cookies \
https://auth.example.com/admin/applications \
-H 'Content-Type: application/json' \
-d '{
"identifier":"example-web",
"name":"Example Web",
"environment":"production"
}'أنشئ client
curl --fail-with-body -b owner.cookies \
https://auth.example.com/admin/clients \
-H 'Content-Type: application/json' \
-d '{
"application_id":"APPLICATION_ID",
"name":"Example Web",
"kind":"web",
"redirect_uris":["https://app.example.com/oauth/callback"],
"scopes":["openid","profile","offline_access"]
}'| النوع | client نموذجي | Secret |
|---|---|---|
browser | SPA / متصفح فقط | لا يوجد |
native | iOS / Android / desktop | لا يوجد |
web | تطبيق ويب server-rendered / backend | يُعاد مرة واحدة؛ للـ backend فقط |
service | آلة إلى آلة | يُعاد مرة واحدة |
Authorization Code + PKCE S256
أنشئ verifier عشوائيًا، واشتق منه challenge من نوع S256، وأنشئ قيمة عشوائية لـ state and nonce. احتفظ بـ verifier/state/nonce فقط طوال مدة معاملة تسجيل الدخول تلك.
GET /oauth/authorize? response_type=code &client_id=CLIENT_ID &redirect_uri=https://app.example.com/oauth/callback &scope=openid profile offline_access &code_challenge=PKCE_CHALLENGE &code_challenge_method=S256 &state=STATE &nonce=NONCE
عند callback، اشترط أن تكون القيمة المعادة state and iss مطابقة للمعاملة/issuer المهيأ قبل تبادل token.
تبادل token
curl --fail-with-body https://auth.example.com/oauth/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'client_id=CLIENT_ID' \ --data-urlencode 'code=AUTHORIZATION_CODE' \ --data-urlencode 'redirect_uri=https://app.example.com/oauth/callback' \ --data-urlencode 'code_verifier=PKCE_VERIFIER'
التحقق من ID token
تحقق من توقيع RS256 باستخدام JWKS الخاص بالـ issuer. تحقق على الأقل من iss, aud, exp, iat والقيمة الأصلية nonce؛ وراعِ nbf, azp and at_hash عند وجودها.
JavaScript / المتصفح
يوفر المستودع حزمة SDK موجهة للمتصفح باسم @openproof/identity. تقوم بإنشاء PKCE/state/nonce، والتحقق من state/issuer في callback، والتحقق من ID token بتوقيع RS256 مقابل JWKS.
import { OpenProofIdentity } from "@openproof/identity";
const identity = new OpenProofIdentity({
issuer: "https://auth.example.com",
clientId: "CLIENT_ID",
redirectUri: "https://app.example.com/oauth/callback",
scopes: ["openid", "profile", "offline_access"]
});
await identity.login();const tokens = await identity.handleCallback(); console.log(tokens.id_token_claims.sub); const profile = await identity.userInfo(tokens.access_token);
لا تضع أبدًا قيمة سرية لـ web or service client secret داخل JavaScript يتم إرساله إلى المستخدم.
Node.js
استخدم عميل OIDC ناضجًا لإطار العمل لديك، أو استخدم fetch() للبروتوكول الموثق. احتفظ ببيانات الاعتماد السرية في بيئة الخادم/مخزن الأسرار.
const body = new URLSearchParams({
grant_type: "authorization_code",
client_id: process.env.OPENPROOF_CLIENT_ID,
code,
redirect_uri: "https://app.example.com/oauth/callback",
code_verifier: verifier
});
const response = await fetch(
"https://auth.example.com/oauth/token",
{
method: "POST",
headers: {
"content-type":
"application/x-www-form-urlencoded"
},
body
}
);
if (!response.ok) {
throw new Error(
`OpenProof token exchange failed: ${response.status}`
);
}
const tokens = await response.json();استخدم مكتبة OIDC/JWT لتخزين JWKS مؤقتًا والتحقق من التوقيع وclaims بدل كتابة التحقق التشفيري بنفسك.
PHP
يمكن لأي مكتبة PHP OAuth/OIDC مُصانة استخدام OpenProof كـ issuer. البروتوكول المباشر هو HTTPS عادي وOAuth بترميز form.
<?php
$payload = http_build_query([
'grant_type' => 'authorization_code',
'client_id' => getenv('OPENPROOF_CLIENT_ID'),
'code' => $_GET['code'],
'redirect_uri' =>
'https://app.example.com/oauth/callback',
'code_verifier' =>
$_SESSION['openproof_pkce_verifier'],
]);
$curl = curl_init(
'https://auth.example.com/oauth/token'
);
curl_setopt_array($curl, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded'
],
]);
$body = curl_exec($curl);
if ($body === false) {
throw new RuntimeException(curl_error($curl));
}تحقق من ID token باستخدام حزمة JWT/OIDC مُصانة وJWKS الخاص بالـ issuer. لا تنفذ التحقق من RSA/JWK بشكل مخصص.
C++
يتم تصدير SDK الخاص بـ C++26 في المستودع باسم openproof.sdk. وهو مستقل عن طبقة النقل، لذا يمكنك الاحتفاظ بمكدس Boost.Beast أو Qt Network أو libcurl الحالي.
import openproof.sdk;
auto config =
openproof::sdk::ClientConfig::create(
"https://auth.example.com",
"CLIENT_ID",
"http://127.0.0.1:49152/callback",
{"openid", "profile", "offline_access"});
openproof::sdk::IdentityClient client{
std::move(config).value()
};
auto login = client.beginLogin();
std::cout <<
login->authorizationUrl()
<< '\n';يوفر SDK أدوات مساعدة لإنشاء معاملة تسجيل الدخول وبناء طلب authorization-code وrefresh وUserInfo. يوجد مثال relying-party مبسط في examples/reference-client.
Python وGo وRust وJava وC# ولغات أخرى
لا تحتاج إلى SDK خاص بـ OpenProof. هيّئ مكتبة OAuth/OIDC متوافقة مع المعايير باستخدام issuer الخاص بـ OpenProof. الحد الأدنى الآمن هو: Discovery ← PKCE/state/nonce ← authorization redirect ← فحوص callback ← token exchange ← التحقق من التوقيع/claims عبر JWKS ← authorization للـ access token.
UserInfo وrefresh
curl --fail-with-body \ https://auth.example.com/oauth/userinfo \ -H 'Authorization: Bearer ACCESS_TOKEN'
curl --fail-with-body \ https://auth.example.com/oauth/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=refresh_token' \ --data-urlencode 'client_id=CLIENT_ID' \ --data-urlencode 'refresh_token=REFRESH_TOKEN'
يتم تدوير refresh token. احفظ الرمز الجديد ذريًا وتخلص من القيمة القديمة. قد تؤدي حماية replay إلى إبطال العائلة كاملة.
احمِ API الخاص بك
سجّل resource بقيمة audience دقيقة وscopes محدودة.
curl --fail-with-body -b owner.cookies \
https://auth.example.com/admin/resources \
-H 'Content-Type: application/json' \
-d '{
"audience":"https://api.example.com/rides",
"name":"Ride API",
"scopes":["rides:read","rides:request"]
}'يجب أن يتحقق backend من صلاحية token وaudience الدقيق وscope المطلوب وقواعد عمل المنتج. صلاحية token وحدها لا تكفي للتفويض.
Introspection
curl --fail-with-body \ https://auth.example.com/oauth/introspect \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=CONFIDENTIAL_CLIENT_ID' \ --data-urlencode 'client_secret=CLIENT_SECRET' \ --data-urlencode 'token=ACCESS_TOKEN'
بوابة OpenProof
بدلًا من ذلك، ضع مسارات المنتج خلف OpenProof وطبّق role وassurance وscope وaudience ضمن سياسة route ثابتة قبل تمرير الطلب إلى backend.
خدمة إلى خدمة
استخدم service وهيئ audiences/scopes المسموح بها، ثم اطلب access token باستخدام client_credentials.
curl --fail-with-body \ https://auth.example.com/oauth/token \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=client_credentials' \ --data-urlencode 'client_id=CLIENT_ID' \ --data-urlencode 'client_secret=CLIENT_SECRET' \ --data-urlencode 'scope=rides:dispatch' \ --data-urlencode 'resource=https://api.example.com/dispatch'
النتيجة هي access token فقط. لا يوجد refresh token ولا جلسة بشرية.
واجهات API للحساب
عند تفعيل الخدمة الذاتية للحساب وتسليم رسائل التحقق، يوفر OpenProof التسجيل وملكية البريد/الهاتف الموثقة وإعادة تعيين كلمة المرور والملفات الشخصية وTOTP ورموز الاسترداد وpasskeys.
| الغرض | Endpoint |
|---|---|
| التسجيل | POST /account/signup |
| التحقق من البريد | POST /account/email/verify |
| بدء إعادة تعيين كلمة المرور | POST /account/password/forgot |
| إكمال إعادة تعيين كلمة المرور | POST /account/password/reset |
| الملف الشخصي | GET/PATCH /account/profile |
| إعداد TOTP | POST /account/totp/start → /complete |
| تسجيل الدخول بـ passkey | POST /auth/passkey/options → /verify |
| الطرق المرتبطة | GET /account/connections |
لا تجعل بريد Google/GitHub مفتاح مستخدم منتجك. يمكن للمستخدم ربط عدة طرق تسجيل دخول مع الاحتفاظ بنفس subject الثابت في OpenProof.
معالجة الأخطاء وحماية الأسرار
تتضمن الأخطاء code ثابتًا ورسالة آمنة للعميل وrequest ID. اعتمد على code/status لا على النص. اعتبر 401 مصادقة مفقودة/غير صالحة، و403 صلاحية/assurance غير كافية، و409 تعارض state، و429 إشارة backoff.
لا تسجّل كلمات المرور أو TOTP/recovery codes أو verification secrets أو authorization codes أو access/refresh tokens أو client secrets السرية أو cookies أو DPoP proofs أو private keys.