hesabixCore/docs/OAuth/OAuth_README.md

331 lines
9.4 KiB
Markdown
Raw Normal View History

# مستندات 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 مبادله کنید:
```bash
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"
```
پاسخ:
```json
{
"access_token": "ACCESS_TOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "REFRESH_TOKEN",
"scope": "read_profile read_business"
}
```
### استفاده از توکن دسترسی
برای دسترسی به API ها، توکن را در header قرار دهید:
```bash
curl -H "Authorization: Bearer ACCESS_TOKEN" \
https://hesabix.ir/oauth/userinfo
```
## API Endpoints
### اطلاعات کاربر
```
GET /oauth/userinfo
Authorization: Bearer ACCESS_TOKEN
```
پاسخ:
```json
{
"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
}
}
```
### تمدید توکن
```bash
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"
```
### لغو توکن
```bash
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
```
پاسخ:
```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_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)
```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 تماس بگیرید.