Accounts API

مستندات کامل احراز هویت OTP، JWT، login، refresh و پروفایل کاربر جاری


معرفی

تمام endpointهای این ماژول با پیشوند /auth/ در دسترس‌اند. ورود اصلی بر پایه OTP است؛ ورود با رمز هم از طریق SimpleJWT پشتیبانی می‌شود.

هدر درخواست‌های خصوصی: Authorization: Bearer <access_token>
لیست Endpointها
1. درخواست کد OTP
POST /auth/request-otp/

دسترسی: عمومی (AllowAny)

OTP ۶ رقمی ساخته می‌شود، ۱۲۰ ثانیه معتبر است. Rate limit پیش‌فرض: حداکثر ۱ درخواست در ۶۰ ثانیه برای هر شماره.

بدنه درخواست
پارامترنوعاجباریتوضیحات
phonenumberstring✓فرمت 09xxxxxxxxx (نرمال‌سازی +98 پشتیبانی می‌شود)
{
  "phonenumber": "09123456789"
}
curl -X POST http://127.0.0.1:8000/auth/request-otp/ \
  -H "Content-Type: application/json" \
  -d "{\"phonenumber\":\"09123456789\"}"
پاسخ موفق (200)
{
  "message": "OTP sent"
}
در محیط توسعه، SMS واقعی ممکن است ارسال نشود و کد OTP در لاگ سرور چاپ شود.
خطاها
  • 400 — شماره نامعتبر / فیلد خالی
  • 429 — rate limit:
    {"detail": "درخواست‌های شما بیش از حد مجاز است. لطفاً بعداً دوباره تلاش کنید."}
2. تایید OTP و دریافت JWT
POST /auth/verify-otp/

دسترسی: عمومی

حداکثر ۳ تلاش اشتباه برای هر OTP. بعد از آن 429 برمی‌گردد.

پارامترنوعاجباری
phonenumberstring✓
otpstring✓
{
  "phonenumber": "09123456789",
  "otp": "123456"
}
پاسخ موفق (200)
{
  "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
  • Access Token lifetime: ۶۰ دقیقه
  • Refresh Token lifetime: ۳۰ روز
  • ROTATE_REFRESH_TOKENS=True و blacklist فعال است
خطاها
  • 401 — OTP اشتباه:
    {"detail": "کد یکبار مصرف وارد شده درست نیست."}
  • 429 — تلاش بیش از حد در verify
  • 404 — کاربر با این شماره وجود ندارد
نمونه فرانت
async function loginWithOtp(phonenumber, otp) {
  const res = await fetch('/auth/verify-otp/', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ phonenumber, otp }),
  });
  if (!res.ok) throw await res.json();
  const tokens = await res.json();
  localStorage.setItem('access', tokens.access);
  localStorage.setItem('refresh', tokens.refresh);
  return tokens;
}
3. ورود با شماره و رمز
POST /auth/login/

SimpleJWT TokenObtainPair — فیلد username برابر phonenumber است.

{
  "phonenumber": "09123456789",
  "password": "your_password"
}
{
  "refresh": "...",
  "access": "..."
}
4. تمدید Access Token
POST /auth/token/refresh/
{"refresh": "YOUR_REFRESH_TOKEN"}

به دلیل rotate، refresh جدید هم برمی‌گردد؛ refresh قبلی blacklist می‌شود.

5. پروفایل کاربر جاری
GET /auth/me/

دسترسی: IsAuthenticated

curl -X GET http://127.0.0.1:8000/auth/me/ \
  -H "Authorization: Bearer ACCESS_TOKEN"
{
  "id": 1,
  "phonenumber": "09123456789",
  "first_name": "علی",
  "last_name": "احمدی",
  "national_code": "0012345678",
  "birthday_date": "1995-01-01",
  "role": "staff",
  "is_staff": true,
  "is_system_admin": false,
  "staff_role": {"id": 1, "code": "secretary", "title": "منشی"},
  "permissions": [
    "properties.list.view",
    "properties.create",
    "agents.view"
  ]
}
انواع کاربری (role)
مقدارمعنی
adminمدیر سیستم — همه دسترسی‌ها
staffکارمند — دسترسی از نقش سازمانی (staff_role)
agentمشاور املاک — ownership روی فایل‌های خودش

جزئیات کامل نقش‌های سازمانی و کاتالوگ دسترسی در مستندات RBAC.

جریان پیشنهادی فرانت
  1. کاربر شماره را وارد می‌کند → POST /auth/request-otp/
  2. کد را وارد می‌کند → POST /auth/verify-otp/
  3. توکن‌ها ذخیره می‌شوند
  4. برای تشخیص نقش و UI → GET /auth/me/
  5. قبل از انقضای access → POST /auth/token/refresh/