مقدمة: لماذا نحتاج إلى التفويض في Rust؟
نادرًا ما تخلو تطبيقات الويب الحديثة من نظام للمصادقة والتفويض. Rust، بفضل أدائها وأمان الذاكرة، أصبحت خيارًا شائعًا لإنشاء الخدمات عالية التحميل. ومع ذلك، قد يبدو العمل مع بروتوكولات مثل OAuth 2.0 وتنسيق JWT معقدًا للمبتدئين.
في هذه المقالة، سنشرح المفاهيم الأساسية لـ OAuth 2.0 و JWT (JSON Web Token) وننفذ نظام تفويض بسيط في Rust باستخدام كريتات شائعة. ستتعلم كيفية حماية نقاط نهاية API الخاصة بك والعمل مع رموز الوصول.
ما هو OAuth 2.0 و JWT؟
قبل كتابة الكود، من المهم فهم النظرية.
OAuth 2.0: بروتوكول الوصول المفوض
OAuth 2.0 هو بروتوكول يسمح للتطبيق بالحصول على وصول محدود إلى موارد المستخدم دون نقل اسم المستخدم وكلمة المرور الخاصة به. تخيل أنك تريد تسجيل الدخول إلى موقع عبر Google أو GitHub - هذا هو OAuth 2.0.
المشاركون الرئيسيون في البروتوكول:
- مالك المورد — المستخدم الذي يملك البيانات.
- العميل — تطبيقك في Rust الذي يريد الحصول على الوصول.
- خادم التفويض — الخادم الذي يصدر الرموز (مثل Google).
- خادم المورد — API الذي يوفر البيانات (مثل Google Drive).
JWT: تنسيق رمز مضغوط
JWT (JSON Web Token) هو معيار مفتوح لإنشاء رموز الوصول. يتكون الرمز من ثلاثة أجزاء مفصولة بنقاط:
- الرأس — نوع الرمز وخوارزمية التوقيع.
- الحمولة — البيانات (المطالبات)، مثل معرف المستخدم أو الدور.
- التوقيع — التوقيع الذي يضمن عدم تغيير الرمز.
مثال على JWT: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNrxP0G7n9G4W7N8Y7J8
JWT مناسب لأنه لا يتطلب تخزين الجلسات على الخادم - جميع المعلومات موجودة بالفعل في الرمز.
إعداد مشروع Rust للتفويض
سنستخدم إطار العمل Actix Web والعديد من الكريتات المساعدة. أنشئ مشروعًا جديدًا:
cargo new rust-auth-examplecd rust-auth-exampleأضف التبعيات في Cargo.toml:
[dependencies]actix-web = "4"actix-rt = "2"serde = { version = "1", features = ["derive"] }serde_json = "1"jsonwebtoken = "9"chrono = { version = "0.4", features = ["serde"] }dotenv = "0.15"env_logger = "0.10"bcrypt = "0.15"هيكل الملفات
لسهولة الاستخدام، سننشئ هيكلًا معياريًا:
src/├── main.rs├── auth.rs├── models.rs└── handlers.rsفي .env سنكتب المفتاح السري لـ JWT:
JWT_SECRET=supersecretkey12345DATABASE_URL=sqlite://users.dbتنفيذ JWT في Rust: من التوليد إلى التحقق
لنبدأ بوحدة auth.rs التي ستكون مسؤولة عن العمل مع JWT.
هياكل JWT
// auth.rsuse serde::{Deserialize, Serialize};use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};use chrono::{Utc, Duration};
#[derive(Debug, Serialize, Deserialize)]pub struct Claims { pub sub: String, // معرف المستخدم pub exp: usize, // وقت الانتهاء pub iat: usize, // وقت الإصدار}
pub fn create_jwt(user_id: &str, secret: &str) -> Result<String, jsonwebtoken::errors::Error> { let now = Utc::now(); let expiration = now + Duration::hours(24); // الرمز صالح لمدة 24 ساعة
let claims = Claims { sub: user_id.to_owned(), exp: expiration.timestamp() as usize, iat: now.timestamp() as usize, };
let token = encode( &Header::default(), &claims,\