حول المحتوى:
شرح آلية OAuth2 وكيفية تنفيذ تسجيل الدخول باستخدام Google و GitHub داخل Django وFastAPI مع أمثلة عملية وجوانب الأمان.
في السنوات الأخيرة أصبح بروتوكول OAuth2 هو المعيار الفعلي لتنفيذ تسجيل الدخول عبر حسابات خارجية مثل Google و GitHub. في هذا الدليل سنشرح آلية عمل OAuth2 بشكل مبسط، ثم ننتقل إلى تطبيقه عمليًا في كل من Django وFastAPI لتسجيل الدخول باستخدام Google و GitHub، مع التركيز على الجوانب الأمنية وأفضل الممارسات.
الكلمة المفتاحية التي سنبني عليها الشرح هي: OAuth2 Django FastAPI، وسنحاول تغطية كل ما تحتاجه لتطبيق تسجيل الدخول الخارجي في مشاريعك الحالية أو القادمة.
OAuth2 هو بروتوكول تفويض (Authorization Protocol)، يسمح لتطبيقك بالوصول إلى بيانات مستخدم في خدمة خارجية (مثل Google أو GitHub) بدون أن يعرف تطبيقك كلمة مرور المستخدم. بدلًا من ذلك يعتمد التطبيق على رمز وصول Access Token يتم إصداره من مزود الهوية (Google, GitHub...).
قبل أن تبدأ في تطبيق OAuth2 في Django أو FastAPI يُفضل أن تكون لديك خلفية عن مصادقة المستخدمين وإدارة الجلسات في Django، ويمكنك مراجعة: دليل شامل حول إطار Django لبناء تطبيقات الويب.
قبل كتابة الكود، تحتاج إلى إنشاء تطبيق في لوحة التحكم الخاصة بكل مزود هوية.
http://localhost:8000/auth/google/callback/ لمشروع Django.http://localhost:8000/auth/google/callback لمشروع FastAPI.http://localhost:8000.http://localhost:8000/auth/github/callback/ لـ Django.http://localhost:8000/auth/github/callback لـ FastAPI.في Django يمكننا إما أن نطبق تدفق OAuth2 يدويًا، أو نعتمد على مكتبة جاهزة. الأكثر استخدامًا هي: social-auth-app-django التي تبسط الكثير من التفاصيل.
أولًا، قم بتثبيت الحزمة:
pip install social-auth-app-django
ثم أضفها إلى INSTALLED_APPS في settings.py:
INSTALLED_APPS = [
...
'django.contrib.auth',
'django.contrib.contenttypes',
'social_django',
...
]
أضف Authentication Backends التي ستستخدم OAuth2:
AUTHENTICATION_BACKENDS = (
'social_core.backends.google.GoogleOAuth2',
'social_core.backends.github.GithubOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
أضف إعدادات المفاتيح (يمكن وضعها في متغيرات بيئة واستخدام os.environ):
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = 'GOOGLE_CLIENT_ID'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'GOOGLE_CLIENT_SECRET'
SOCIAL_AUTH_GITHUB_KEY = 'GITHUB_CLIENT_ID'
SOCIAL_AUTH_GITHUB_SECRET = 'GITHUB_CLIENT_SECRET'
أضف مسارات social_django في urls.py الرئيسي:
from django.urls import path, include
urlpatterns = [
...
path('auth/', include('social_django.urls', namespace='social')),
]
الآن ستجد مسارات مثل: /auth/login/google-oauth2/ و /auth/complete/google-oauth2/ وغيرها متاحة تلقائيًا.
في قالب تسجيل الدخول يمكنك إضافة أزرار لتسجيل الدخول عبر Google و GitHub:
<a href="{% url 'social:begin' 'google-oauth2' %}">
تسجيل الدخول باستخدام Google
</a>
<a href="{% url 'social:begin' 'github' %}">
تسجيل الدخول باستخدام GitHub
</a>
عند الضغط على الزر، سيتم توجيه المستخدم إلى Google أو GitHub، وبعد التفويض سيعود إلى تطبيقك، والمكتبة ستتعامل تلقائيًا مع إنشاء/تحديث المستخدم وتسجيل الدخول.
تقوم social-auth-app-django بإنشاء جداول لإدارة الارتباط بين المستخدمين المحليين وحساباتهم على مزودات OAuth2. يمكنك تشغيل:
python manage.py migrate
إذا أردت تخصيص عملية إنشاء المستخدم (مثل ربطه بجروب أو ضبط صلاحيات)، يمكنك استخدام SOCIAL_AUTH_PIPELINE في settings.py وإضافة دوال مخصصة.
في FastAPI يمكننا استخدام مكتبة httpx أو requests للتعامل مع مزودات OAuth2 يدويًا، أو الاعتماد على مكتبات طرف ثالث. هنا سنشرح الفكرة الأساسية يدويًا مع Google و GitHub.
pip install fastapi uvicorn[standard] httpx python-multipart
# main.py
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse, HTMLResponse
import httpx
import os
app = FastAPI()
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET")
GOOGLE_REDIRECT_URI = "http://localhost:8000/auth/google/callback"
GITHUB_CLIENT_ID = os.getenv("GITHUB_CLIENT_ID")
GITHUB_CLIENT_SECRET = os.getenv("GITHUB_CLIENT_SECRET")
GITHUB_REDIRECT_URI = "http://localhost:8000/auth/github/callback"
@app.get("/auth/google/login")
async def google_login():
google_auth_endpoint = "https://accounts.google.com/o/oauth2/v2/auth"
scope = "openid email profile"
redirect_uri = (
f"{google_auth_endpoint}"
f"?client_id={GOOGLE_CLIENT_ID}"
f"&response_type=code"
f"&redirect_uri={GOOGLE_REDIRECT_URI}"
f"&scope={scope}"
f"&access_type=offline"
f"&prompt=consent"
)
return RedirectResponse(redirect_uri)
سيتم إعادة توجيه المستخدم إلى شاشة الدخول في Google، وبعد الموافقة سيتم إرجاعه إلى /auth/google/callback مع ?code=....
@app.get("/auth/google/callback")
async def google_callback(request: Request):
code = request.query_params.get("code")
if not code:
return HTMLResponse("لم يتم توفير كود التفويض", status_code=400)
token_endpoint = "https://oauth2.googleapis.com/token"
async with httpx.AsyncClient() as client:
token_response = await client.post(
token_endpoint,
data={
"code": code,
"client_id": GOOGLE_CLIENT_ID,
"client_secret": GOOGLE_CLIENT_SECRET,
"redirect_uri": GOOGLE_REDIRECT_URI,
"grant_type": "authorization_code",
},
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
token_data = token_response.json()
access_token = token_data.get("access_token")
if not access_token:
return HTMLResponse("فشل في الحصول على Access Token", status_code=400)
# طلب بيانات المستخدم
userinfo_endpoint = "https://www.googleapis.com/oauth2/v2/userinfo"
async with httpx.AsyncClient() as client:
userinfo_response = await client.get(
userinfo_endpoint,
headers={"Authorization": f"Bearer {access_token}"},
)
userinfo = userinfo_response.json()
email = userinfo.get("email")
name = userinfo.get("name")
# في هذه النقطة يمكنك:
# 1- البحث عن المستخدم في قاعدة البيانات
# 2- إنشاء مستخدم جديد إن لم يكن موجودًا
# 3- إصدار JWT أو إنشاء جلسة (حسب تصميم تطبيقك)
content = f"مرحبًا {name} - بريدك: {email}"
return HTMLResponse(content)
نكرر الفكرة نفسها مع GitHub مع اختلاف الروابط ونوع البيانات.
@app.get("/auth/github/login")
async def github_login():
github_auth_endpoint = "https://github.com/login/oauth/authorize"
redirect_uri = (
f"{github_auth_endpoint}"
f"?client_id={GITHUB_CLIENT_ID}"
f"&redirect_uri={GITHUB_REDIRECT_URI}"
f"&scope=user:email"
)
return RedirectResponse(redirect_uri)
@app.get("/auth/github/callback")
async def github_callback(request: Request):
code = request.query_params.get("code")
if not code:
return HTMLResponse("لم يتم توفير كود التفويض", status_code=400)
token_endpoint = "https://github.com/login/oauth/access_token"
async with httpx.AsyncClient() as client:
token_response = await client.post(
token_endpoint,
data={
"client_id": GITHUB_CLIENT_ID,
"client_secret": GITHUB_CLIENT_SECRET,
"code": code,
"redirect_uri": GITHUB_REDIRECT_URI,
},
headers={"Accept": "application/json"},
)
token_data = token_response.json()
access_token = token_data.get("access_token")
if not access_token:
return HTMLResponse("فشل في الحصول على Access Token من GitHub", status_code=400)
# طلب بيانات المستخدم
user_endpoint = "https://api.github.com/user"
async with httpx.AsyncClient() as client:
user_response = await client.get(
user_endpoint,
headers={"Authorization": f"Bearer {access_token}"},
)
userinfo = user_response.json()
username = userinfo.get("login")
email = userinfo.get("email")
content = f"مرحبًا {username} - البريد: {email}"
return HTMLResponse(content)
يمكنك في هذه المرحلة ربط عملية تسجيل الدخول بنظام JWT أو نظام جلسات خاص بك. إذا كنت تبني API فقط، قد تفضّل إصدار JWT Token للمستخدم بعد إتمام OAuth2 واستخدامه في طلبات API اللاحقة.
auth_user.@login_required أو LoginRequiredMixin.بما أن موضوع OAuth2 حساس ويتعامل مع بيانات المستخدمين، فهناك نقاط ينبغي الانتباه لها:
Access Token أو Authorization Code.client_secret في متغيرات البيئة أو أنظمة إدارة الأسرار (Secrets Manager)، وعدم رفعها في Git.إذا كنت تركز على:
social-auth-app-django خيار ممتاز وسريع التهيئة.إذا كان مشروعك يعتمد على Django REST Framework وتريد إضافة OAuth2 فوقه، فاقرأ: دليل شامل لإطار Django REST مع أمثلة، ثم اربط بين المصادقة في DRF ونتائج تسجيل الدخول عبر Google/GitHub.
تنفيذ OAuth2 Django FastAPI لم يعد أمرًا معقدًا كما كان في السابق، بفضل المكتبات الجاهزة ودعم البروتوكول في أغلب مزودات الهوية. في هذا الدليل:
يمكنك الآن دمج OAuth2 في مشاريعك سواء كانت مبنية على Django أو FastAPI، وتوفير تسجيل دخول سلس وآمن للمستخدمين عبر حساباتهم في Google أو GitHub مع الحفاظ على التحكم الكامل في بياناتهم داخل تطبيقك.
شرح آلية OAuth2 وكيفية تنفيذ تسجيل الدخول باستخدام Google و GitHub داخل Django وFastAPI مع أمثلة عملية وجوانب الأمان.
مساحة اعلانية