1 OAuth_Complete_Documentation
Hesabix edited this page 2025-08-16 04:50:24 +03:30
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

مستندات کامل سیستم OAuth 2.0 - Hesabix

📋 فهرست مطالب

  1. معرفی OAuth 2.0
  2. معماری سیستم
  3. بخش مدیریت
  4. بخش کاربری
  5. API Documentation
  6. نحوه اتصال
  7. امنیت
  8. مثال‌های عملی
  9. عیب‌یابی
  10. پشتیبانی

🚀 معرفی OAuth 2.0

OAuth 2.0 یک پروتکل استاندارد برای احراز هویت و مجوزدهی است که به برنامه‌های خارجی اجازه می‌دهد بدون نیاز به رمز عبور، به حساب کاربران دسترسی داشته باشند.

مزایای OAuth 2.0:

  • امنیت بالا: عدم اشتراک‌گذاری رمز عبور
  • کنترل دسترسی: محدود کردن دسترسی‌ها با Scope
  • قابلیت لغو: امکان لغو دسترسی در هر زمان
  • استاندارد: سازگار با پروتکل‌های جهانی
  • IP Whitelist: کنترل دسترسی بر اساس IP
  • Rate Limiting: محدودیت تعداد درخواست

🏗️ معماری سیستم

اجزای اصلی:

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Client App    │    │  OAuth Server   │    │  Resource Owner │
│  (Third Party)  │◄──►│   (Hesabix)     │◄──►│     (User)      │
└─────────────────┘    └─────────────────┘    └─────────────────┘

جریان OAuth:

  1. Client Registration: ثبت برنامه در بخش مدیریت
  2. Authorization Request: درخواست مجوز از کاربر
  3. User Consent: تأیید کاربر
  4. Authorization Code: دریافت کد مجوز
  5. Token Exchange: تبدیل کد به Access Token
  6. Resource Access: دسترسی به منابع

پایگاه داده:

-- جداول OAuth
oauth_application     -- برنامه‌های ثبت شده
oauth_scope          -- محدوده‌های دسترسی
oauth_authorization_code  -- کدهای مجوز موقت
oauth_access_token   -- توکن‌های دسترسی

⚙️ بخش مدیریت

1. دسترسی به بخش مدیریت

مدیریت سیستم → تنظیمات سیستم → تب "برنامه‌های OAuth"

2. آمار کلی

سیستم چهار کارت آمار نمایش می‌دهد:

  • کل برنامه‌ها: تعداد کل برنامه‌های ثبت شده
  • فعال: تعداد برنامه‌های فعال
  • غیرفعال: تعداد برنامه‌های غیرفعال
  • جدید (7 روز): برنامه‌های ایجاد شده در هفته گذشته

3. ایجاد برنامه جدید

مراحل ایجاد:

  1. کلیک روی "ایجاد برنامه جدید"
  2. پر کردن فرم:
    • نام برنامه: نام منحصر به فرد برنامه
    • توضیحات: توضیح کاربرد برنامه
    • آدرس وب‌سایت: URL اصلی برنامه
    • آدرس بازگشت: URL callback برنامه
    • محدودیت درخواست: تعداد درخواست مجاز در ساعت

تنظیمات امنیتی:

IP Whitelist:
- در صورت خالی بودن: از هر IP مجاز است
- افزودن IP: 192.168.1.1 یا 192.168.1.0/24
- پشتیبانی از CIDR notation
- Validation خودکار آدرس‌های IP
Scope Management:
read_profile     - دسترسی به اطلاعات پروفایل
write_profile    - تغییر اطلاعات پروفایل
read_business    - دسترسی به اطلاعات کسب و کار
write_business   - تغییر اطلاعات کسب و کار
read_financial   - دسترسی به اطلاعات مالی
write_financial  - تغییر اطلاعات مالی
read_contacts    - دسترسی به لیست مخاطبین
write_contacts   - تغییر لیست مخاطبین
read_documents   - دسترسی به اسناد
write_documents  - تغییر اسناد
admin_access     - دسترسی مدیریتی

4. مدیریت برنامه‌ها

کارت برنامه:

  • وضعیت: فعال/غیرفعال با رنگ‌بندی
  • Client ID: شناسه یکتا برنامه
  • تاریخ ایجاد: تاریخ ثبت برنامه
  • توضیحات: شرح برنامه

عملیات موجود:

دکمه‌های اصلی:
  • ویرایش: تغییر اطلاعات برنامه
  • آمار: مشاهده آمار استفاده
  • فعال/غیرفعال: تغییر وضعیت برنامه
منوی سه نقطه:
  • بازسازی کلید: تولید Client Secret جدید
  • لغو توکن‌ها: لغو تمام توکن‌های فعال
  • حذف: حذف کامل برنامه

5. اطلاعات امنیتی

پس از ایجاد برنامه، اطلاعات زیر نمایش داده می‌شود:

Client ID:     mL0qT1fkIL6MCJfxIPAh7nM2cQ7ykxEy
Client Secret: goM7latD9akY83z2O2e9IIEYED3Re6sRMd36f5cUSYHm389PPSqYbFHSX8GtQ9H1

⚠️ هشدار: این اطلاعات را در جای امنی ذخیره کنید!


👤 بخش کاربری

1. صفحه مجوزدهی

هنگام اتصال برنامه خارجی، کاربر به صفحه زیر هدایت می‌شود:

┌─────────────────────────────────────┐
│           مجوزدهی OAuth             │
├─────────────────────────────────────┤
│                                     │
│  [آیکون برنامه] نام برنامه         │
│  توضیحات برنامه...                 │
│                                     │
│  این برنامه درخواست دسترسی به:      │
│  ✓ خواندن اطلاعات پروفایل          │
│  ✓ خواندن اطلاعات کسب و کار         │
│                                     │
│  [لغو] [تأیید]                     │
└─────────────────────────────────────┘

2. اطلاعات نمایش داده شده:

  • نام و لوگوی برنامه
  • توضیحات برنامه
  • محدوده‌های دسترسی درخواستی
  • دکمه‌های تأیید/لغو

3. تصمیم کاربر:

  • تأیید: ادامه فرآیند OAuth
  • لغو: بازگشت به برنامه اصلی

📡 API Documentation

Base URL

https://your-domain.com/oauth

1. Authorization Endpoint

درخواست مجوز:

GET /oauth/authorize

پارامترهای مورد نیاز:

{
  "response_type": "code",
  "client_id": "mL0qT1fkIL6MCJfxIPAh7nM2cQ7ykxEy",
  "redirect_uri": "https://your-app.com/callback",
  "scope": "read_profile read_business",
  "state": "random_string_for_csrf"
}

پاسخ موفق:

HTTP/1.1 302 Found
Location: https://your-app.com/callback?code=AUTHORIZATION_CODE&state=random_string

2. Token Endpoint

درخواست Access Token:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

پارامترهای مورد نیاز:

{
  "grant_type": "authorization_code",
  "client_id": "mL0qT1fkIL6MCJfxIPAh7nM2cQ7ykxEy",
  "client_secret": "goM7latD9akY83z2O2e9IIEYED3Re6sRMd36f5cUSYHm389PPSqYbFHSX8GtQ9H1",
  "code": "AUTHORIZATION_CODE",
  "redirect_uri": "https://your-app.com/callback"
}

پاسخ موفق:

{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "def50200...",
  "scope": "read_profile read_business"
}

3. User Info Endpoint

درخواست اطلاعات کاربر:

GET /oauth/userinfo
Authorization: Bearer ACCESS_TOKEN

پاسخ موفق:

{
  "id": 123,
  "email": "user@example.com",
  "name": "نام کاربر",
  "profile": {
    "phone": "+989123456789",
    "address": "تهران، ایران"
  }
}

4. Refresh Token Endpoint

تمدید Access Token:

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

پارامترهای مورد نیاز:

{
  "grant_type": "refresh_token",
  "client_id": "mL0qT1fkIL6MCJfxIPAh7nM2cQ7ykxEy",
  "client_secret": "goM7latD9akY83z2O2e9IIEYED3Re6sRMd36f5cUSYHm389PPSqYbFHSX8GtQ9H1",
  "refresh_token": "def50200..."
}

5. Revoke Endpoint

لغو Token:

POST /oauth/revoke
Authorization: Bearer ACCESS_TOKEN

پارامترهای مورد نیاز:

{
  "token": "ACCESS_TOKEN_OR_REFRESH_TOKEN"
}

6. Discovery Endpoint

دریافت اطلاعات OAuth Server:

GET /.well-known/oauth-authorization-server

پاسخ:

{
  "issuer": "https://hesabix.ir",
  "authorization_endpoint": "https://hesabix.ir/oauth/authorize",
  "token_endpoint": "https://hesabix.ir/oauth/token",
  "userinfo_endpoint": "https://hesabix.ir/oauth/userinfo",
  "revocation_endpoint": "https://hesabix.ir/oauth/revoke",
  "response_types_supported": ["code"],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "token_endpoint_auth_methods_supported": ["client_secret_post"],
  "scopes_supported": [
    "read_profile",
    "write_profile",
    "read_business",
    "write_business",
    "read_financial",
    "write_financial",
    "read_contacts",
    "write_contacts",
    "read_documents",
    "write_documents",
    "admin_access"
  ]
}

🔗 نحوه اتصال

1. ثبت برنامه

ابتدا برنامه خود را در بخش مدیریت ثبت کنید:

// اطلاعات مورد نیاز
const appInfo = {
  name: "My Application",
  description: "توضیح برنامه من",
  website: "https://myapp.com",
  redirectUri: "https://myapp.com/oauth/callback",
  allowedScopes: ["read_profile", "read_business"],
  ipWhitelist: ["192.168.1.0/24"], // اختیاری
  rateLimit: 1000
};

2. پیاده‌سازی OAuth Flow

مرحله 1: درخواست مجوز

function initiateOAuth() {
  const params = new URLSearchParams({
    response_type: 'code',
    client_id: 'YOUR_CLIENT_ID',
    redirect_uri: 'https://myapp.com/oauth/callback',
    scope: 'read_profile read_business',
    state: generateRandomString()
  });
  
  window.location.href = `https://hesabix.com/oauth/authorize?${params}`;
}

مرحله 2: دریافت Authorization Code

// در callback URL
function handleCallback() {
  const urlParams = new URLSearchParams(window.location.search);
  const code = urlParams.get('code');
  const state = urlParams.get('state');
  
  if (code && state) {
    exchangeCodeForToken(code);
  }
}

مرحله 3: تبدیل Code به Token

async function exchangeCodeForToken(code) {
  const response = await fetch('https://hesabix.com/oauth/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: 'YOUR_CLIENT_ID',
      client_secret: 'YOUR_CLIENT_SECRET',
      code: code,
      redirect_uri: 'https://myapp.com/oauth/callback'
    })
  });
  
  const tokenData = await response.json();
  // ذخیره token
  localStorage.setItem('access_token', tokenData.access_token);
  localStorage.setItem('refresh_token', tokenData.refresh_token);
}

مرحله 4: استفاده از Access Token

async function getUserInfo() {
  const response = await fetch('https://hesabix.com/oauth/userinfo', {
    headers: {
      'Authorization': `Bearer ${localStorage.getItem('access_token')}`
    }
  });
  
  const userData = await response.json();
  return userData;
}

3. مدیریت Token

تمدید Access Token:

async function refreshAccessToken() {
  const response = await fetch('https://hesabix.com/oauth/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      grant_type: 'refresh_token',
      client_id: 'YOUR_CLIENT_ID',
      client_secret: 'YOUR_CLIENT_SECRET',
      refresh_token: localStorage.getItem('refresh_token')
    })
  });
  
  const tokenData = await response.json();
  localStorage.setItem('access_token', tokenData.access_token);
  localStorage.setItem('refresh_token', tokenData.refresh_token);
}

لغو Token:

async function revokeToken() {
  await fetch('https://hesabix.com/oauth/revoke', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${localStorage.getItem('access_token')}`
    },
    body: JSON.stringify({
      token: localStorage.getItem('access_token')
    })
  });
  
  localStorage.removeItem('access_token');
  localStorage.removeItem('refresh_token');
}

🔒 امنیت

1. محدودیت‌های IP

// بررسی IP در backend
function checkIpWhitelist($clientIp, $whitelist) {
  if (empty($whitelist)) {
    return true; // همه IP ها مجاز
  }
  
  foreach ($whitelist as $allowedIp) {
    if (ipInRange($clientIp, $allowedIp)) {
      return true;
    }
  }
  
  return false;
}

2. محدودیت‌های Scope

// بررسی دسترسی در backend
function checkScope($requestedScope, $allowedScopes) {
  $requestedScopes = explode(' ', $requestedScope);
  
  foreach ($requestedScopes as $scope) {
    if (!in_array($scope, $allowedScopes)) {
      return false;
    }
  }
  
  return true;
}

3. Rate Limiting

// محدودیت درخواست
function checkRateLimit($clientId, $limit) {
  $requests = getRequestCount($clientId, '1 hour');
  return $requests < $limit;
}

4. Token Security

  • Access Token: عمر 1 ساعت
  • Refresh Token: عمر 30 روز
  • JWT Signature: امضای دیجیتال
  • Token Revocation: امکان لغو فوری

5. نکات امنیتی مهم

  1. HTTPS اجباری: تمام ارتباطات باید روی HTTPS باشد
  2. State Parameter: همیشه از state parameter استفاده کنید
  3. Client Secret: Client Secret را در کد سمت کلاینت قرار ندهید
  4. Token Storage: توکن‌ها را در جای امنی ذخیره کنید
  5. Scope Validation: همیشه scope ها را بررسی کنید

💻 مثال‌های عملی

مثال 1: اپلیکیشن وب

<!DOCTYPE html>
<html>
<head>
    <title>OAuth Example</title>
</head>
<body>
    <button onclick="login()">ورود با Hesabix</button>
    
    <script>
        const CLIENT_ID = 'YOUR_CLIENT_ID';
        const REDIRECT_URI = 'https://myapp.com/callback';
        
        function login() {
            const params = new URLSearchParams({
                response_type: 'code',
                client_id: CLIENT_ID,
                redirect_uri: REDIRECT_URI,
                scope: 'read_profile',
                state: Math.random().toString(36)
            });
            
            window.location.href = `https://hesabix.com/oauth/authorize?${params}`;
        }
        
        // بررسی callback
        if (window.location.search.includes('code=')) {
            handleCallback();
        }
        
        async function handleCallback() {
            const code = new URLSearchParams(window.location.search).get('code');
            
            const response = await fetch('https://hesabix.com/oauth/token', {
                method: 'POST',
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                body: new URLSearchParams({
                    grant_type: 'authorization_code',
                    client_id: CLIENT_ID,
                    client_secret: 'YOUR_CLIENT_SECRET',
                    code: code,
                    redirect_uri: REDIRECT_URI
                })
            });
            
            const data = await response.json();
            console.log('Token received:', data);
        }
    </script>
</body>
</html>

مثال 2: اپلیکیشن موبایل

// React Native Example
import { Linking } from 'react-native';

class OAuthManager {
  constructor() {
    this.clientId = 'YOUR_CLIENT_ID';
    this.redirectUri = 'myapp://oauth/callback';
  }
  
  async login() {
    const authUrl = `https://hesabix.com/oauth/authorize?` +
      `response_type=code&` +
      `client_id=${this.clientId}&` +
      `redirect_uri=${encodeURIComponent(this.redirectUri)}&` +
      `scope=read_profile&` +
      `state=${Math.random().toString(36)}`;
    
    await Linking.openURL(authUrl);
  }
  
  async handleCallback(url) {
    const code = url.match(/code=([^&]*)/)?.[1];
    if (code) {
      await this.exchangeCodeForToken(code);
    }
  }
  
  async exchangeCodeForToken(code) {
    const response = await fetch('https://hesabix.com/oauth/token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        grant_type: 'authorization_code',
        client_id: this.clientId,
        client_secret: 'YOUR_CLIENT_SECRET',
        code: code,
        redirect_uri: this.redirectUri
      })
    });
    
    const data = await response.json();
    await AsyncStorage.setItem('access_token', data.access_token);
  }
}

مثال 3: اپلیکیشن سرور

# Python Flask Example
from flask import Flask, request, redirect, session
import requests

app = Flask(__name__)
app.secret_key = 'your-secret-key'

CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
REDIRECT_URI = 'https://myapp.com/oauth/callback'

@app.route('/login')
def login():
    auth_url = f'https://hesabix.com/oauth/authorize?' + \
               f'response_type=code&' + \
               f'client_id={CLIENT_ID}&' + \
               f'redirect_uri={REDIRECT_URI}&' + \
               f'scope=read_profile'
    
    return redirect(auth_url)

@app.route('/oauth/callback')
def callback():
    code = request.args.get('code')
    
    # تبدیل code به token
    token_response = requests.post('https://hesabix.com/oauth/token', data={
        'grant_type': 'authorization_code',
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'code': code,
        'redirect_uri': REDIRECT_URI
    })
    
    token_data = token_response.json()
    session['access_token'] = token_data['access_token']
    
    return 'Login successful!'

@app.route('/user-info')
def user_info():
    headers = {'Authorization': f"Bearer {session['access_token']}"}
    response = requests.get('https://hesabix.com/oauth/userinfo', headers=headers)
    
    return response.json()

مثال 4: کلاس کامل JavaScript

class HesabixOAuth {
  constructor(clientId, redirectUri) {
    this.clientId = clientId;
    this.redirectUri = redirectUri;
    this.baseUrl = 'https://hesabix.com';
  }

  // شروع فرآیند OAuth
  authorize(scopes = ['read_profile']) {
    const state = this.generateState();
    const params = new URLSearchParams({
      client_id: this.clientId,
      redirect_uri: this.redirectUri,
      response_type: 'code',
      scope: scopes.join(' '),
      state: state
    });
    
    localStorage.setItem('oauth_state', state);
    window.location.href = `${this.baseUrl}/oauth/authorize?${params}`;
  }

  // پردازش callback
  async handleCallback() {
    const urlParams = new URLSearchParams(window.location.search);
    const code = urlParams.get('code');
    const state = urlParams.get('state');
    const savedState = localStorage.getItem('oauth_state');

    if (state !== savedState) {
      throw new Error('State mismatch');
    }

    if (!code) {
      throw new Error('Authorization code not found');
    }

    const tokens = await this.exchangeCode(code);
    localStorage.setItem('access_token', tokens.access_token);
    localStorage.setItem('refresh_token', tokens.refresh_token);
    
    return tokens;
  }

  // مبادله کد با توکن
  async exchangeCode(code) {
    const response = await fetch(`${this.baseUrl}/oauth/token`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: new URLSearchParams({
        grant_type: 'authorization_code',
        client_id: this.clientId,
        client_secret: 'YOUR_CLIENT_SECRET', // در سرور ذخیره شود
        code: code,
        redirect_uri: this.redirectUri
      })
    });

    if (!response.ok) {
      throw new Error('Token exchange failed');
    }

    return await response.json();
  }

  // دریافت اطلاعات کاربر
  async getUserInfo() {
    const token = localStorage.getItem('access_token');
    const response = await fetch(`${this.baseUrl}/oauth/userinfo`, {
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      throw new Error('Failed to get user info');
    }

    return await response.json();
  }

  // تمدید توکن
  async refreshToken() {
    const refreshToken = localStorage.getItem('refresh_token');
    const response = await fetch(`${this.baseUrl}/oauth/token`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: new URLSearchParams({
        grant_type: 'refresh_token',
        client_id: this.clientId,
        client_secret: 'YOUR_CLIENT_SECRET',
        refresh_token: refreshToken
      })
    });

    if (!response.ok) {
      throw new Error('Token refresh failed');
    }

    const tokens = await response.json();
    localStorage.setItem('access_token', tokens.access_token);
    localStorage.setItem('refresh_token', tokens.refresh_token);
    
    return tokens;
  }

  generateState() {
    return Math.random().toString(36).substring(2, 15);
  }
}

// استفاده
const oauth = new HesabixOAuth('YOUR_CLIENT_ID', 'https://yourapp.com/callback');

// شروع OAuth
oauth.authorize(['read_profile', 'read_business']);

// در صفحه callback
oauth.handleCallback().then(tokens => {
  console.log('OAuth successful:', tokens);
  // دریافت اطلاعات کاربر
  return oauth.getUserInfo();
}).then(userInfo => {
  console.log('User info:', userInfo);
});

🔧 عیب‌یابی

خطاهای رایج:

1. invalid_client

علت: Client ID یا Secret اشتباه راه حل: بررسی صحت Client ID و Secret

2. invalid_grant

علت: Authorization Code نامعتبر یا منقضی شده راه حل: درخواست مجدد Authorization Code

3. invalid_scope

علت: Scope درخواستی مجاز نیست راه حل: بررسی Scope های مجاز در پنل مدیریت

4. access_denied

علت: کاربر دسترسی را لغو کرده راه حل: درخواست مجدد از کاربر

5. server_error

علت: خطای سرور راه حل: بررسی لاگ‌های سرور

کدهای خطا:

const errorCodes = {
  'invalid_request': 'درخواست نامعتبر',
  'invalid_client': 'Client ID یا Secret اشتباه',
  'invalid_grant': 'کد مجوز نامعتبر',
  'unauthorized_client': 'برنامه مجاز نیست',
  'unsupported_grant_type': 'نوع grant پشتیبانی نمی‌شود',
  'invalid_scope': 'Scope نامعتبر',
  'access_denied': 'دسترسی رد شد',
  'server_error': 'خطای سرور',
  'temporarily_unavailable': 'سرویس موقتاً در دسترس نیست'
};

لاگ‌ها:

# مشاهده لاگ‌های OAuth
tail -f /var/log/hesabix/oauth.log

# پاک کردن کش
php bin/console cache:clear

# بررسی وضعیت سرور
php bin/console debug:router | grep oauth

📞 پشتیبانی

اطلاعات تماس:

  • ایمیل: support@hesabix.com
  • تلفن: 021-12345678
  • ساعات کاری: شنبه تا چهارشنبه، 9 صبح تا 6 عصر
  • تلگرام: @hesabix_support

سوالات متداول:

Q: چگونه Client Secret را تغییر دهم؟

A: در پنل مدیریت، روی منوی سه نقطه برنامه کلیک کرده و "بازسازی کلید" را انتخاب کنید.

Q: آیا می‌توانم چندین Redirect URI داشته باشم؟

A: خیر، هر برنامه فقط یک Redirect URI می‌تواند داشته باشد.

Q: توکن‌ها چه مدت اعتبار دارند؟

A: Access Token 1 ساعت و Refresh Token 30 روز اعتبار دارد.

Q: چگونه IP Whitelist را تنظیم کنم؟

A: در زمان ایجاد یا ویرایش برنامه، IP های مجاز را اضافه کنید. اگر خالی باشد، از هر IP مجاز است.

Q: آیا می‌توانم Scope ها را بعداً تغییر دهم؟

A: بله، در بخش ویرایش برنامه می‌توانید Scope ها را تغییر دهید.

گزارش باگ:

برای گزارش باگ، لطفاً اطلاعات زیر را ارسال کنید:

  1. نوع خطا: کد خطا و پیام
  2. مراحل تولید: مراحل دقیق تولید خطا
  3. اطلاعات برنامه: Client ID و نام برنامه
  4. لاگ‌ها: لاگ‌های مربوطه
  5. مرورگر/سیستم عامل: اطلاعات محیط اجرا

📚 منابع بیشتر


📋 چک‌لیست پیاده‌سازی

قبل از شروع:

  • برنامه در پنل مدیریت ثبت شده
  • Client ID و Secret دریافت شده
  • Redirect URI تنظیم شده
  • Scope های مورد نیاز تعیین شده
  • IP Whitelist تنظیم شده (در صورت نیاز)

پیاده‌سازی:

  • Authorization Request پیاده‌سازی شده
  • Callback Handler پیاده‌سازی شده
  • Token Exchange پیاده‌سازی شده
  • Error Handling پیاده‌سازی شده
  • Token Storage پیاده‌سازی شده

تست:

  • Authorization Flow تست شده
  • Token Exchange تست شده
  • User Info API تست شده
  • Error Scenarios تست شده
  • Security Features تست شده

نسخه مستندات: 1.0
تاریخ آخرین به‌روزرسانی: 2025-08-16
وضعیت: فعال
توسعه‌دهنده: Hesabix Team