خلاصة القول
نطاقات OAuth 2.0 هي سلاسل صلاحيات تحدد ما يمكن أن يفعله رمز الوصول. استخدم التنسيق المورد:الإجراء مثل pets:read أو orders:write. اطلب النطاقات أثناء التفويض، وتحقق منها على نقاط نهاية API. تطبق Modern PetstoreAPI نطاقات للوصول بالقراءة/الكتابة إلى الحيوانات الأليفة والطلبات وبيانات المستخدم.
مقدمة
يرغب تطبيق تابع لجهة خارجية في قراءة مخزون متجر الحيوانات الأليفة الخاص بك. هل يجب أن يكون لديه وصول كامل لإنشاء الطلبات وحذف الحيوانات الأليفة وإدارة المستخدمين؟ لا. يجب أن يقرأ المخزون فقط.
نطاقات OAuth 2.0 تحل هذه المشكلة. تحدد النطاقات الصلاحيات التي يمتلكها رمز الوصول. يطلب التطبيق نطاق inventory:read. تتحقق واجهة برمجة التطبيقات (API) الخاصة بك من أن الرمز يحتوي على هذا النطاق قبل إرجاع البيانات.
Modern PetstoreAPI تطبق نطاقات دقيقة لجميع الموارد: الحيوانات الأليفة، الطلبات، المخزون، والمستخدمين.
إذا كنت تختبر واجهات برمجة تطبيقات OAuth، فإن Apidog يساعدك على اختبار التحقق من النطاق وتدفقات التفويض.
ما هي نطاقات OAuth 2.0؟
النطاقات هي سلاسل صلاحيات مضمنة في رموز وصول OAuth.
تنسيق النطاق
pets:read - قراءة بيانات الحيوانات الأليفة
pets:write - إنشاء/تحديث الحيوانات الأليفة
orders:read - قراءة الطلبات
orders:write - إنشاء الطلبات
admin:all - وصول إداري كامل
النطاق في تدفق OAuth
1. طلب التفويض:
GET /oauth/authorize?
client_id=app123&
scope=pets:read orders:read&
redirect_uri=https://app.com/callback
2. موافقة المستخدم:
يرغب تطبيق "PetFinder" في:
- قراءة حيواناتك الأليفة
- قراءة طلباتك
[سماح] [رفض]
3. رمز الوصول:
{
"access_token": "eyJhbGc...",
"scope": "pets:read orders:read",
"expires_in": 3600
}
4. طلب API:
GET /v1/pets
Authorization: Bearer eyJhbGc...
200 OK (تم التحقق من النطاق)
كيف تعمل النطاقات
الرمز يحتوي على نطاقات
يتضمن رمز الوصول النطاقات الممنوحة:
// JWT مفكك
{
"sub": "user-456",
"scope": "pets:read orders:read",
"exp": 1710331200
}
API يتحقق من النطاقات
app.get('/v1/pets', requireScope('pets:read'), async (req, res) => {
const pets = await getPets();
res.json(pets);
});
app.post('/v1/pets', requireScope('pets:write'), async (req, res) => {
const pet = await createPet(req.body);
res.status(201).json(pet);
});
function requireScope(requiredScope) {
return (req, res, next) => {
const token = extractToken(req);
const decoded = verifyToken(token);
if (!decoded.scope.includes(requiredScope)) {
return res.status(403).json({
error: 'insufficient_scope',
message: `يتطلب نطاق: ${requiredScope}`
});
}
next();
};
}
تصميم النطاقات
اصطلاحات تسمية النطاقات
نمط المورد:الإجراء:
pets:read
pets:write
orders:read
orders:write
users:read
users:write
نطاقات دقيقة:
pets:read
pets:create
pets:update
pets:delete
نطاقات البدل:
pets:* - جميع عمليات الحيوانات الأليفة
*:read - قراءة جميع الموارد
admin:* - وصول إداري كامل
التسلسل الهرمي للنطاق
admin:all
├── pets:*
│ ├── pets:read
│ ├── pets:write
│ └── pets:delete
├── orders:*
│ ├── orders:read
│ └── orders:write
└── users:*
├── users:read
└── users:write
تطبيق التحقق من النطاق
نهج الوسيطة (Middleware)
function requireScopes(...requiredScopes) {
return (req, res, next) => {
const token = extractToken(req);
const decoded = verifyToken(token);
const tokenScopes = decoded.scope.split(' ');
const hasAllScopes = requiredScopes.every(scope =>
tokenScopes.includes(scope) || tokenScopes.includes('admin:all')
);
if (!hasAllScopes) {
return res.status(403).json({
error: 'insufficient_scope',
required: requiredScopes,
provided: tokenScopes
});
}
req.user = decoded;
next();
};
}
// الاستخدام
app.get('/v1/pets', requireScopes('pets:read'), getPets);
app.post('/v1/pets', requireScopes('pets:write'), createPet);
app.delete('/v1/pets/:id', requireScopes('pets:delete'), deletePet);
نهج المُزخرف (TypeScript)
function RequireScopes(...scopes: string[]) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
const req = args[0];
const res = args[1];
const token = extractToken(req);
const decoded = verifyToken(token);
if (!hasScopes(decoded.scope, scopes)) {
return res.status(403).json({ error: 'insufficient_scope' });
}
return originalMethod.apply(this, args);
};
};
}
// Usage
class PetsController {
@RequireScopes('pets:read')
async getPets(req, res) {
const pets = await this.petService.findAll();
res.json(pets);
}
@RequireScopes('pets:write')
async createPet(req, res) {
const pet = await this.petService.create(req.body);
res.status(201).json(pet);
}
}
كيف تستخدم Modern PetstoreAPI النطاقات
النطاقات المتاحة
pets:read - قراءة بيانات الحيوانات الأليفة
pets:write - إنشاء/تحديث الحيوانات الأليفة
pets:delete - حذف الحيوانات الأليفة
orders:read - قراءة الطلبات
orders:write - إنشاء الطلبات
inventory:read - قراءة المخزون
inventory:write - تحديث المخزون
users:read - قراءة ملف تعريف المستخدم
users:write - تحديث ملف تعريف المستخدم
admin:all - وصول كامل
التحقق من النطاق
GET /v1/pets
Authorization: Bearer token_with_pets:read
200 OK
POST /v1/pets
Authorization: Bearer token_with_pets:read
403 Forbidden
{
"error": "insufficient_scope",
"required": ["pets:write"],
"provided": ["pets:read"]
}
انظر وثائق OAuth الخاصة بـ Modern PetstoreAPI.
اختبار النطاقات باستخدام Apidog
Apidog يدعم اختبار نطاقات OAuth:
- قم بتكوين مصادقة OAuth 2.0
- اطلب نطاقات محددة
- اختبر نقاط النهاية بنطاقات مختلفة
- تحقق من استجابات 403 للنطاقات غير الكافية
أفضل الممارسات
- استخدم نطاقات دقيقة - مثل
pets:readوليسread_all - اتبع اصطلاحات التسمية - تنسيق
المورد:الإجراء - وثّق جميع النطاقات - أدرجها في وثائق API
- تحقق من كل طلب - لا تثق بالعميل
- أعد أخطاء واضحة - أظهر النطاقات المطلوبة مقابل المتوفرة
- استخدم مبدأ الحد الأدنى من الامتيازات - اطلب الحد الأدنى من النطاقات المطلوبة
الخلاصة
توفر نطاقات OAuth 2.0 تحكمًا دقيقًا في الوصول. استخدم تنسيق المورد:الإجراء، وتحقق من كل طلب، ووثّق جميع النطاقات. توضح Modern PetstoreAPI تطبيقًا للنطاقات جاهزًا للإنتاج.
الأسئلة الشائعة
ما الفرق بين النطاقات والأدوار؟
النطاقات هي صلاحيات لرموز الوصول. الأدوار هي مجموعات مستخدمين ذات صلاحيات مخصصة.
هل يمكنك الحصول على نطاقات متعددة؟
نعم، افصلها بمسافات: pets:read orders:read users:write
كيف تقوم بإلغاء النطاقات؟
قم بإلغاء رمز الوصول أو أصدر رمزًا جديدًا بنطاقات مختلفة.
هل يجب أن تكون النطاقات في JWT؟
نعم، قم بتضمينها في مطالبة scope للتحقق عديم الحالة.
ما مدى دقة النطاقات؟
وازن بين الدقة وسهولة الاستخدام. عادةً ما تكون pets:read و pets:write كافيتين.
