OAuth 2.0 و JWT التوثيق في Rust: دليل خطوة بخطوة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا OAuth 2.0 و JWT في Rust؟

\n\n

نادرًا ما تستغني تطبيقات الويب الحديثة عن نظام المصادقة والتفويض. OAuth 2.0 هو المعيار الصناعي لتفويض الوصول، و JWT (JSON Web Tokens) هي طريقة مضغوطة وآمنة لنقل الادعاءات بين الأطراف. Rust، بفضل أدائها وأمان الذاكرة، أصبحت أكثر شيوعًا لإنشاء خوادم عالية التحميل. في هذه المقالة، سنشرح عمليًا كيفية تنفيذ تفويض OAuth 2.0 مع JWT في Rust باستخدام الكريتات الشائعة والأساليب الحديثة.

\n\n

1. إعداد المشروع وتثبيت التبعيات

\n\n

لنبدأ بإنشاء مشروع جديد في Rust وإضافة التبعيات اللازمة. سنستخدم actix-web لخادم الويب، jsonwebtoken للعمل مع JWT، serde للتسلسل، و reqwest لطلبات HTTP إلى موفري OAuth الخارجيين.

\n\n
# Cargo.toml\n[package]\nname = "oauth-jwt-rust"\nversion = "0.1.0"\nedition = "2021"\n\n[dependencies]\nactix-web = "4"\nactix-rt = "2"\njsonwebtoken = "9"\nserde = { version = "1.0", features = ["derive"] }\nserde_json = "1.0"\nreqwest = { version = "0.12", features = ["json"] }\ntokio = { version = "1", features = ["full"] }\ndotenv = "0.15"\nchrono = { version = "0.4", features = ["serde"] }\nuuid = { version = "1", features = ["v4"] }
\n\n

لننشئ ملف .env لتخزين المفاتيح السرية:

\n\n
JWT_SECRET=your_super_secret_key_here\nGITHUB_CLIENT_ID=your_github_client_id\nGITHUB_CLIENT_SECRET=your_github_client_secret
\n\n

2. الهيكل الأساسي لرموز JWT

\n\n

يتكون JWT من ثلاثة أجزاء: الرأس، الحمولة، والتوقيع. سنحدد الهياكل للعمل مع الرموز.

\n\n
// src/jwt.rs\nuse chrono::{Utc, Duration};\nuse jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};\nuse serde::{Deserialize, Serialize};\n\n#[derive(Debug, Serialize, Deserialize)]\npub struct Claims {\n    pub sub: String,       // معرف المستخدم\n    pub email: String,     // البريد الإلكتروني للمستخدم\n    pub exp: usize,        // وقت الانتهاء\n    pub iat: usize,        // وقت الإصدار\n}\n\npub fn create_jwt(user_id: &str, email: &str) -> Result {\n    let now = Utc::now();\n    let expiration = now + Duration::hours(24); // الرمز صالح لمدة 24 ساعة\n\n    let claims = Claims {\n        sub: user_id.to_string(),\n        email: email.to_string(),\n        exp: expiration.timestamp() as usize,\n        iat: now.timestamp() as usize,\n    };\n\n    let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET must be set");\n    encode(\n        &Header::default(),\n        &claims,\n        &EncodingKey::from_secret(secret.as_bytes()),\n    )\n}\n\npub fn validate_jwt(token: &str) -> Result {\n    let secret = std::env::var("JWT_SECRET").expect("JWT_SECRET must be set");\n    let token_data = decode::(\n        token,\n        &DecodingKey::from_secret(secret.as_bytes()),\n        &Validation::default(),\n    )?;\n    Ok(token_data.claims)\n}
\n\n

3. تنفيذ OAuth 2.0 مع GitHub

\n\n

لننظر في السيناريو الكلاسيكي لـ OAuth 2.0 — التفويض عبر GitHub. يتم توجيه المستخدم إلى GitHub، وبعد التأكيد يحصل على رمز نستبدله بـ access token.

\n\n

3.1. نقطة النهاية لبدء تدفق OAuth

\n\n
// src/oauth.rs\nuse actix_web::{web, HttpResponse, HttpRequest};\nuse reqwest::Client;\nuse serde_json::Value;\n\npub async fn github_login() -> HttpResponse {\n    let client_id = std::env::var("GITHUB_CLIENT_ID").unwrap();\n    let redirect_uri = "http://localhost:8080/auth/github/callback";\n    \n    let auth_url = format!(\n        "https://github.com/login/oauth/authorize?client_id={}&redirect_uri={}&scope=user:email",\n        client_id, redirect_uri\n    );\n    \n    HttpRes                

المدونات

توصيات الكتب