Genyleap/Docs
OpenProof / التطوير

اربط أي تطبيق عبر OAuth/OIDC القياسي.

لا يعتمد OpenProof على لغة برمجة عند حدود البروتوكول. استخدم حزم SDK المرفقة حيث تكون مفيدة، أو تكامل من أي لغة تدعم HTTPS وOAuth 2.0/OpenID Connect.

نموذج التكامل

التدفقAuthorization Code + PKCE
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

عناوين URLاستبدل auth.example.com
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تتطلب جلسة owner
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

curlclient ويب
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
browserSPA / متصفح فقطلا يوجد
nativeiOS / Android / desktopلا يوجد
webتطبيق ويب server-rendered / backendيُعاد مرة واحدة؛ للـ backend فقط
serviceآلة إلى آلةيُعاد مرة واحدة

Authorization Code + PKCE S256

أنشئ verifier عشوائيًا، واشتق منه challenge من نوع S256، وأنشئ قيمة عشوائية لـ state and nonce. احتفظ بـ verifier/state/nonce فقط طوال مدة معاملة تسجيل الدخول تلك.

طلب authorizationمفاهيمي
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

curlapplication/x-www-form-urlencoded
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.

javascriptclient متصفح عام
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();
javascriptcallback
const tokens = await identity.handleCallback();

console.log(tokens.id_token_claims.sub);

const profile =
  await identity.userInfo(tokens.access_token);
عملاء المتصفح لا يملكون client secret.

لا تضع أبدًا قيمة سرية لـ web or service client secret داخل JavaScript يتم إرساله إلى المستخدم.

Node.js

استخدم عميل OIDC ناضجًا لإطار العمل لديك، أو استخدم fetch() للبروتوكول الموثق. احتفظ ببيانات الاعتماد السرية في بيئة الخادم/مخزن الأسرار.

javascriptتبادل token على الخادم
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.

phptoken exchange
<?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 الحالي.

c++إعداد SDK
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. الحد الأدنى الآمن هو: DiscoveryPKCE/state/nonceauthorization redirect ← فحوص callbacktoken exchange ← التحقق من التوقيع/claims عبر JWKSauthorization للـ access token.

UserInfo وrefresh

curlUserInfo
curl --fail-with-body \
  https://auth.example.com/oauth/userinfo \
  -H 'Authorization: Bearer ACCESS_TOKEN'
curlrefresh 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تسجيل resource
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

curlbackend سري
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.

curlgrant للآلة
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
إعداد TOTPPOST /account/totp/start/complete
تسجيل الدخول بـ passkeyPOST /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.