hesabixCore/docs/OAuth/OAuth_README.md
2025-08-16 12:13:39 +00:00

9.4 KiB

مستندات OAuth Hesabix

مقدمه

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

مراحل پیاده‌سازی

1. ثبت برنامه

ابتدا باید برنامه خود را در پنل مدیریت Hesabix ثبت کنید:

  1. وارد پنل مدیریت شوید
  2. به بخش "تنظیمات سیستم" بروید
  3. تب "برنامه‌های OAuth" را انتخاب کنید
  4. روی "برنامه جدید" کلیک کنید
  5. اطلاعات برنامه را وارد کنید:
    • نام برنامه
    • توضیحات
    • آدرس وب‌سایت
    • آدرس بازگشت (Redirect URI)
    • محدوده‌های دسترسی مورد نیاز

2. دریافت Client ID و Client Secret

پس از ثبت برنامه، Client ID و Client Secret به شما داده می‌شود. این اطلاعات را در جای امنی ذخیره کنید.

محدوده‌های دسترسی (Scopes)

Scope توضیحات
read_profile دسترسی به اطلاعات پروفایل کاربر
write_profile ویرایش اطلاعات پروفایل کاربر
read_business دسترسی به اطلاعات کسب‌وکار
write_business ویرایش اطلاعات کسب‌وکار
read_accounting دسترسی به اطلاعات حسابداری
write_accounting ویرایش اطلاعات حسابداری
read_reports دسترسی به گزارش‌ها
write_reports ایجاد و ویرایش گزارش‌ها
admin دسترسی مدیریتی کامل

OAuth Flow

Authorization Code Flow (توصیه شده)

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

کاربر را به آدرس زیر هدایت کنید:

GET /oauth/authorize

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

  • client_id: شناسه برنامه شما
  • redirect_uri: آدرس بازگشت (باید با آدرس ثبت شده مطابقت داشته باشد)
  • response_type: همیشه code
  • scope: محدوده‌های دسترسی (با فاصله جدا شده)
  • state: مقدار تصادفی برای امنیت (اختیاری)

مثال:

https://hesabix.ir/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=https://yourapp.com/callback&response_type=code&scope=read_profile%20read_business&state=random_string

مرحله 2: دریافت کد مجوز

پس از تایید کاربر، به آدرس redirect_uri با پارامتر code هدایت می‌شود:

https://yourapp.com/callback?code=AUTHORIZATION_CODE&state=random_string

مرحله 3: دریافت توکن دسترسی

کد مجوز را با Client Secret مبادله کنید:

curl -X POST https://hesabix.ir/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "code=AUTHORIZATION_CODE" \
  -d "redirect_uri=https://yourapp.com/callback"

پاسخ:

{
  "access_token": "ACCESS_TOKEN",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "REFRESH_TOKEN",
  "scope": "read_profile read_business"
}

استفاده از توکن دسترسی

برای دسترسی به API ها، توکن را در header قرار دهید:

curl -H "Authorization: Bearer ACCESS_TOKEN" \
  https://hesabix.ir/oauth/userinfo

API Endpoints

اطلاعات کاربر

GET /oauth/userinfo
Authorization: Bearer ACCESS_TOKEN

پاسخ:

{
  "sub": 123,
  "email": "user@example.com",
  "name": "نام کاربر",
  "mobile": "09123456789",
  "profile": {
    "full_name": "نام کامل",
    "mobile": "09123456789",
    "email": "user@example.com",
    "date_register": "2024-01-01",
    "active": true
  }
}

تمدید توکن

curl -X POST https://hesabix.ir/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "refresh_token=REFRESH_TOKEN"

لغو توکن

curl -X POST https://hesabix.ir/oauth/revoke \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=ACCESS_TOKEN" \
  -d "token_type_hint=access_token"

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_accounting",
    "write_accounting",
    "read_reports",
    "write_reports",
    "admin"
  ]
}

نکات امنیتی

  1. HTTPS اجباری: تمام ارتباطات باید روی HTTPS باشد
  2. State Parameter: همیشه از state parameter استفاده کنید
  3. توکن‌های کوتاه‌مدت: توکن‌های دسترسی 1 ساعت اعتبار دارند
  4. Refresh Token: برای تمدید توکن از refresh token استفاده کنید
  5. Client Secret: Client Secret را در کد سمت کلاینت قرار ندهید

مثال پیاده‌سازی (JavaScript)

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

  // شروع فرآیند 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);
});

پشتیبانی

برای سوالات و مشکلات مربوط به OAuth، با تیم پشتیبانی Hesabix تماس بگیرید.