هر برنامهای را از طریق 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 متعلق به origin حساب/مدیریت OpenProof است و نباید به دامنهٔ محصول شما کپی شود.
از Discovery شروع کنید
https://auth.example.com/.well-known/openid-configuration https://auth.example.com/.well-known/jwks.json
Discovery روش ترجیحی برای کلاینتهای قابلاستفادهٔ مجدد است تا endpointهای authorization، token، UserInfo، introspection و سایر endpointهای مرتبط با پروتکل را کشف کنند.
محصول خود را ثبت کنید
یک owner فعال با 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 / دسکتاپ | ندارد |
web | برنامهٔ وب server-rendered / بکاند | فقط یکبار برگردانده میشود؛ فقط بکاند |
service | ماشینبهماشین | فقط یکبار برگردانده میشود |
Authorization Code + PKCE S256
یک verifier تصادفی تولید کنید، challenge نوع S256 را از آن بسازید و مقدار تصادفی state و 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 و iss باید پیش از token exchange با تراکنش/issuer پیکربندیشده مطابقت داشته باشد.
تبادل توکن
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 و at_hash را در صورت وجود رعایت کنید.
JavaScript / مرورگر
repository یک بستهٔ SDK متمرکز بر مرورگر با نام @openproof/identityارائه میکند. این SDK مقادیر 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 یا service را در JavaScriptی که برای کاربر ارسال میشود قرار ندهید.
Node.js
از یک client بالغ OIDC برای framework خود استفاده کنید، یا برای پروتکل مستندشده از fetch() native استفاده کنید. credentialهای محرمانه را در محیط سرور/secret store نگه دارید.
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();برای cache کردن JWKS، بررسی امضا و اعتبارسنجی claimها از یک کتابخانهٔ OIDC/JWT استفاده کنید؛ اعتبارسنجی رمزنگاری را خودتان از صفر پیادهسازی نکنید.
PHP
هر کتابخانهٔ نگهداریشدهٔ OAuth/OIDC در PHP میتواند OpenProof را بهعنوان issuer استفاده کند. پروتکل مستقیم، HTTPS معمولی و OAuth با form encoding است.
<?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 را بهشکل ad hoc پیادهسازی نکنید.
C++
SDK مربوط به C++26 در repository با نام openproof.sdk صادر میشود. این SDK نسبت به transport مستقل است تا بتوانید stack فعلی 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 helper ارائه میکند. یک نمونهٔ حداقلی 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 ← اعتبارسنجی امضا/claim با 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ها rotate میشوند. توکن جدید را بهصورت atomic ذخیره و مقدار قبلی را حذف کنید. محافظت در برابر replay میتواند کل خانوادهٔ توکنها را revoke کند.
از API خود محافظت کنید
یک resource با audience دقیق و scopeهای محدود ثبت کنید.
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"]
}'بکاند باید اعتبار توکن، audience دقیق، scope لازم و قواعد کسبوکار محصول را بررسی کند. معتبر بودن توکن بهتنهایی مجوز کافی نیست.
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'
gateway مربوط به OpenProof
راه دیگر این است که routeهای محصول را پشت OpenProof قرار دهید و پیش از proxy شدن به بکاند، role، assurance، scope و audience را در policy ثابت route اعمال کنید.
سرویسبهسرویس
از یک service استفاده کنید، audience/scopeهای مجاز را provision کنید و سپس با 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های حساب
وقتی self-service حساب و delivery تأیید فعال باشد، OpenProof ثبتنام، مالکیت تأییدشدهٔ ایمیل/تلفن، reset رمز عبور، profile، TOTP، recovery code و passkey را ارائه میکند.
| کاربرد | Endpoint |
|---|---|
| ثبتنام | POST /account/signup |
| تأیید ایمیل | POST /account/email/verify |
| شروع reset رمز عبور | POST /account/password/forgot |
| تکمیل reset رمز عبور | 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 key نکنید. کاربر میتواند چند روش ورود را متصل کند و در عین حال همان subject پایدار OpenProof را حفظ کند.
مدیریت خطا و حفاظت از secrets
خطاها شامل code پایدار، پیام امن برای client و request ID هستند. منطق برنامه را بر اساس code/status بنویسید، نه متن پیام. 401 را نبود/نامعتبر بودن authentication، 403 را authority/assurance ناکافی، 409 را تداخل state و 429 را سیگنال backoff در نظر بگیرید.
هرگز رمز عبور، TOTP/recovery code، verification secret، authorization code، access/refresh token، client secret محرمانه، cookie، DPoP proof یا private key را log نکنید.