hesabixCore/docs/OAuth/OAuth_Complete_Documentation.md

957 lines
27 KiB
Markdown
Raw Permalink Normal View History

# مستندات کامل سیستم OAuth 2.0 - Hesabix
## 📋 فهرست مطالب
1. [معرفی OAuth 2.0](#معرفی-oauth-20)
2. [معماری سیستم](#معماری-سیستم)
3. [بخش مدیریت](#بخش-مدیریت)
4. [بخش کاربری](#بخش-کاربری)
5. [API Documentation](#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:** دسترسی به منابع
### پایگاه داده:
```sql
-- جداول 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
#### درخواست مجوز:
```http
GET /oauth/authorize
```
#### پارامترهای مورد نیاز:
```javascript
{
"response_type": "code",
"client_id": "mL0qT1fkIL6MCJfxIPAh7nM2cQ7ykxEy",
"redirect_uri": "https://your-app.com/callback",
"scope": "read_profile read_business",
"state": "random_string_for_csrf"
}
```
#### پاسخ موفق:
```http
HTTP/1.1 302 Found
Location: https://your-app.com/callback?code=AUTHORIZATION_CODE&state=random_string
```
### 2. Token Endpoint
#### درخواست Access Token:
```http
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
```
#### پارامترهای مورد نیاز:
```javascript
{
"grant_type": "authorization_code",
"client_id": "mL0qT1fkIL6MCJfxIPAh7nM2cQ7ykxEy",
"client_secret": "goM7latD9akY83z2O2e9IIEYED3Re6sRMd36f5cUSYHm389PPSqYbFHSX8GtQ9H1",
"code": "AUTHORIZATION_CODE",
"redirect_uri": "https://your-app.com/callback"
}
```
#### پاسخ موفق:
```json
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "def50200...",
"scope": "read_profile read_business"
}
```
### 3. User Info Endpoint
#### درخواست اطلاعات کاربر:
```http
GET /oauth/userinfo
Authorization: Bearer ACCESS_TOKEN
```
#### پاسخ موفق:
```json
{
"id": 123,
"email": "user@example.com",
"name": "نام کاربر",
"profile": {
"phone": "+989123456789",
"address": "تهران، ایران"
}
}
```
### 4. Refresh Token Endpoint
#### تمدید Access Token:
```http
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
```
#### پارامترهای مورد نیاز:
```javascript
{
"grant_type": "refresh_token",
"client_id": "mL0qT1fkIL6MCJfxIPAh7nM2cQ7ykxEy",
"client_secret": "goM7latD9akY83z2O2e9IIEYED3Re6sRMd36f5cUSYHm389PPSqYbFHSX8GtQ9H1",
"refresh_token": "def50200..."
}
```
### 5. Revoke Endpoint
#### لغو Token:
```http
POST /oauth/revoke
Authorization: Bearer ACCESS_TOKEN
```
#### پارامترهای مورد نیاز:
```javascript
{
"token": "ACCESS_TOKEN_OR_REFRESH_TOKEN"
}
```
### 6. Discovery Endpoint
#### دریافت اطلاعات OAuth Server:
```http
GET /.well-known/oauth-authorization-server
```
#### پاسخ:
```json
{
"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. ثبت برنامه
ابتدا برنامه خود را در بخش مدیریت ثبت کنید:
```javascript
// اطلاعات مورد نیاز
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: درخواست مجوز
```javascript
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
```javascript
// در 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
```javascript
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
```javascript
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:
```javascript
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:
```javascript
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
```javascript
// بررسی 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
```javascript
// بررسی دسترسی در backend
function checkScope($requestedScope, $allowedScopes) {
$requestedScopes = explode(' ', $requestedScope);
foreach ($requestedScopes as $scope) {
if (!in_array($scope, $allowedScopes)) {
return false;
}
}
return true;
}
```
### 3. Rate Limiting
```javascript
// محدودیت درخواست
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: اپلیکیشن وب
```html
<!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: اپلیکیشن موبایل
```javascript
// 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
# 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
```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
**علت:** خطای سرور
**راه حل:** بررسی لاگ‌های سرور
### کدهای خطا:
```javascript
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': 'سرویس موقتاً در دسترس نیست'
};
```
### لاگ‌ها:
```bash
# مشاهده لاگ‌های 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. **مرورگر/سیستم عامل:** اطلاعات محیط اجرا
---
## 📚 منابع بیشتر
- [RFC 6749 - OAuth 2.0](https://tools.ietf.org/html/rfc6749)
- [OAuth 2.0 Security Best Practices](https://tools.ietf.org/html/draft-ietf-oauth-security-topics)
- [OpenID Connect](https://openid.net/connect/)
- [OAuth 2.0 Authorization Code Flow](https://auth0.com/docs/protocols/oauth2/oauth2-authorization-code-flow)
---
## 📋 چک‌لیست پیاده‌سازی
### قبل از شروع:
- [ ] برنامه در پنل مدیریت ثبت شده
- [ ] 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