A robust blogging platform REST API built with Django Rest Framework and JWT authentication, allowing users to create, view, and comment on posts with proper access control for editing.
You can find the API documentation in Postman here: Blogify_API
- JWT Authentication: Secure token-based authentication with refresh capabilities
- Social Authentication: Google OAuth2 integration for simplified login
- Custom User Model: Extended user model with additional fields like phone number
- Post Management: Create, read, update, and delete blog posts
- Comment System: Add and manage comments on posts
- Permission Controls: Author-based permissions for content modification
- Egyptian Phone Validation: Custom validator for Egyptian phone numbers
- Slug Generation: Auto-generated slugs for SEO-friendly URLs
- Token Blacklisting: Security feature for proper logout functionality
- Django 5.1: Web framework
- Django REST Framework: API toolkit
- SimpleJWT: JWT authentication
- Social Auth: Google OAuth2 integration via python-social-auth
- SQLite: Database (can be easily switched to other databases)
-
Clone the repository:
git clone https://github.com/yourusername/Blogify_API.git cd Blogify_API
-
Create and activate a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
-
Set up environment variables: Create a
.env
file in the project root with:SECRET_KEY=your_secret_key SOCIAL_AUTH_GOOGLE_OAUTH2_KEY=your_google_oauth_key SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET=your_google_oauth_secret
-
Run migrations:
python manage.py migrate
-
Create a superuser:
python manage.py createsuperuser
-
Run the development server:
python manage.py runserver
Endpoint | Method | Description | Request Body | Response |
---|---|---|---|---|
/auth/register/ |
POST | Register a new user | username , password , email , phone , first_name , last_name |
JWT tokens |
/auth/login/ |
POST | Login existing user | email , password |
JWT tokens |
/auth/logout/ |
POST | Logout user | refresh token |
Success message |
/auth/token/ |
POST | Get JWT tokens | email , password |
Access and refresh tokens |
/auth/token/refresh/ |
POST | Refresh JWT token | refresh token |
New access token |
Endpoint | Method | Description |
---|---|---|
/auth/social/login/google-oauth2/ |
GET | Initiate Google OAuth login flow |
/auth/social/complete/google-oauth2/ |
GET | OAuth callback URL for Google |
For more fine-grained control:
/auth/google/login/
- Custom endpoint that redirects to Google auth/auth/google/callback/
- Custom endpoint for handling Google callbacks
Endpoint | Method | Description | Authentication | Permissions |
---|---|---|---|---|
/api/post/ |
GET | List all posts | Optional | All users |
/api/post/ |
POST | Create new post | Required | Authenticated users |
/api/post/{slug}/ |
GET | Get post details | Optional | All users |
/api/post/{slug}/ |
PUT/PATCH | Update post | Required | Post author only |
/api/post/{slug}/ |
DELETE | Delete post | Required | Post author only |
/api/comment/ |
GET | List all comments | Optional | All users |
/api/comment/ |
POST | Create comment | Required | Authenticated users |
/api/comment/{id}/ |
GET | Get comment details | Optional | All users |
/api/comment/{id}/ |
PUT/PATCH | Update comment | Required | Comment author only |
/api/comment/{id}/ |
DELETE | Delete comment | Required | Comment author only |
The application uses a clean URL structure with route registration through Django's URL patterns:
urlpatterns = [
path('auth/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('auth/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('auth/register/', RegisterView.as_view(), name='register'),
path('auth/login/', LoginView.as_view(), name='login'),
path('auth/logout/', LogoutView.as_view(), name='logout'),
path('auth/social/', include('social_django.urls', namespace='social')),
path('api/', include(route.urls)),
]
API routes are automatically registered using Django REST Framework's DefaultRouter:
route = DefaultRouter()
route.register(r'post', PostsViewSet, basename="post")
route.register(r'comment', CommentsViewSet, basename="comment")
username
: Username for the useremail
: Email address (used as login identifier)first_name
: User's first namelast_name
: User's last namephone
: Egyptian phone number with validator
title
: Post titlecontent
: Post contentcreated_at
: Creation timestampupdated_at
: Last update timestampauthor
: User who created the postslug
: SEO-friendly URL path (auto-generated)
content
: Comment textcreated_at
: Creation timestampupdated_at
: Last update timestampauthor
: User who created the commentpost
: Associated post
- Register with required user details
- Login with email and password
- Receive JWT access and refresh tokens
- Use access token in Authorization header as "Bearer {token}"
- Refresh token when expired
- Navigate to
/auth/social/login/google-oauth2/
- Complete Google authentication
- Redirected back to your application
- Authenticated session created
- Call
/auth/google/login/
to get Google authorization URL - Redirect user to Google for authentication
- Google redirects to your callback URL with authorization code
- Call
/auth/google/callback/
with the code - Receive JWT tokens for authenticated session
AUTHENTICATION_BACKENDS = (
'social_core.backends.google.GoogleOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
'openid',
]
The API returns appropriate HTTP status codes with error messages:
400 Bad Request
: Invalid input data401 Unauthorized
: Authentication failure403 Forbidden
: Permission denied404 Not Found
: Resource not found
- Create a project in the Google Developer Console
- Enable the Google+ API
- Create OAuth credentials
- Set authorized JavaScript origins to
http://localhost:8000
- Set authorized redirect URIs to
http://localhost:8000/auth/social/complete/google-oauth2/
- Add your client ID and secret to the
.env
file
This project is licensed under the MIT License - see the LICENSE file for details.