Skip to main content

Django Googler is a simple way to integrate Google Auth Platform with your Django project.

Project description

Django Googler

Simple Google OAuth authentication for Django. Returns JWT tokens for your API.

What It Does

  1. User clicks "Sign in with Google"
  2. Google handles authentication
  3. Your Django app gets JWT tokens + user info
  4. Use JWT tokens for authenticated API requests

Installation

uv add django-googler

or

pip install django-googler

Quick Setup

1. Add to settings.py

INSTALLED_APPS = [
    # ...
    "rest_framework",
    "rest_framework_simplejwt",
    "rest_framework_simplejwt.token_blacklist",  # Optional: for logout
    "django_googler",
]

# Get these from Google Cloud Console
GOOGLE_OAUTH_CLIENT_ID = "your-client-id"
GOOGLE_OAUTH_CLIENT_SECRET = "your-client-secret"

2. Add URLs

# urls.py
from django.urls import path, include

urlpatterns = [
    # Django Rest Framework OAuth API views
    path("api/auth/", include("django_googler.urls.drf")),
    # Standard Django OAuth views (non django rest framework)
    path("auth/", include("django_googler.urls.default")),
]

3. Run Migrations

python manage.py migrate

Done! You now have these endpoints:

  • GET /api/auth/google/login/ - Get Google OAuth URL
  • POST /api/auth/google/callback/ - Exchange code for JWT tokens
  • GET /api/auth/me/ - Get current user (requires JWT)
  • POST /api/auth/logout/ - Logout (requires JWT)

You can also use the Django views directly:

  • GET /auth/google/login/ - To automatically start Google OAuth which will automatically redirect you to /auth/google/callback/
  • GET /auth/google/callback/ - To handle Google's callback
  • To logout you'll use a standard Django logout view or logout method to end the User's session

Usage

API Examples:

curl http://localhost:8000/api/auth/google/login/

Yields:

{
  "authorization_url": "https://accounts.google.com/...",
  "state": "..."
}

Opening authorization_url in a new tab will start the Google OAuth flow and automatically redirect you to /api/auth/google/callback/. If you set DJANGO_GOOGLER_ALLOW_GET_ON_DRF_CALLBACK = True in settings.py, your automatic redirect to /api/auth/googler/callback/ will automatically provider your auth tokens in the response such as:

{
  "access": "eyJ0eXAiOiJKV1Q...",  // JWT access token (short-lived)
  "refresh": "eyJ0eXAiOiJKV1Q...", // JWT refresh token (long-lived)
  "user": {
    "id": 1,
    "email": "user@example.com",
    "username": "user",
    "first_name": "John",
    "last_name": "Doe"
  }
}

From here you can do an authenticated request to /api/auth/me/ to get the user's information:

curl http://localhost:8000/api/auth/me/ \
  -H "Authorization: Bearer <access_token>"

To refresh the access token, you can use the /api/auth/google/refresh/ endpoint:

curl -X POST http://localhost:8000/api/auth/google/refresh/ \
  -H "Content-Type: application/json" \
  -d '{"refresh": "<refresh_token>"}'

This is a standard JWT refresh endpoint provided by rest_framework_simplejwt with TokenRefreshView.

Frontend Flow

1. Get Google OAuth URL

const redirect_uri = 'http://localhost:3000/auth/callback';
const apiBaseUrl = 'http://localhost:8000';
const loginApiEndpoint = `${apiBaseUrl}/api/auth/google/login/`;
const requestUrl = `${loginApiEndpoint}?redirect_uri=${redirect_uri}`;
const response = await fetch(requestUrl);
const data = await response.json();
// data = { "authorization_url": "https://accounts.google.com/...", "state": "..." }

// Redirect user to Google
window.location.href = data.authorization_url;

2. Handle Google's Callback

After Google redirects back to your frontend with a code and state:

// Get the callback data from the current URL
const currentUrl = new URL(window.location.href);
const googleCallbackData = Object.fromEntries(currentUrl.searchParams);

// Send the callback data to the backend
const apiBaseUrl = 'http://localhost:8000';
const callbackApiEndpoint = `${apiBaseUrl}/api/auth/google/callback/`;
const response = await fetch(callbackApiEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(googleCallbackData)
});

const responseData = await response.json();
/* responseData = {
  "access": "eyJ0eXAiOiJKV1Q...",  // JWT access token (short-lived)
  "refresh": "eyJ0eXAiOiJKV1Q...", // JWT refresh token (long-lived)
  "user": {
    "id": 1,
    "email": "user@example.com",
    "username": "user",
    "first_name": "John",
    "last_name": "Doe"
  }
} */

// Save tokens
localStorage.setItem('access_token', responseData.access);
localStorage.setItem('refresh_token', responseData.refresh);

3. Make Authenticated Requests

const apiBaseUrl = 'http://localhost:8000';
const meApiEndpoint = `${apiBaseUrl}/api/auth/me/`;
const response = await fetch(meApiEndpoint, {
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('access_token')}`
  }
});

const responseData = await response.json();
/* responseData = {
  "id": 1,
  "email": "user@example.com",
  "username": "user",
  "first_name": "John",
  "last_name": "Doe"
} */

4. Logout

const apiBaseUrl = 'http://localhost:8000';
const logoutApiEndpoint = `${apiBaseUrl}/api/auth/logout/`;
const response = await fetch(logoutApiEndpoint, {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${localStorage.getItem('access_token')}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    refresh: localStorage.getItem('refresh_token')
  })
});

localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');

Configuration

Required Settings

GOOGLE_OAUTH_CLIENT_ID = "your-client-id"
GOOGLE_OAUTH_CLIENT_SECRET = "your-client-secret"

Optional Settings

# Return Google tokens in callback response (for calling Google APIs from frontend)
# Default: False
GOOGLE_OAUTH_RETURN_TOKENS = False

# Revoke Google access on logout
# Default: False
GOOGLE_OAUTH_REVOKE_ON_LOGOUT = False

# Save Google OAuth tokens to database (for backend Google API calls)
# Default: True
GOOGLE_OAUTH_SAVE_TOKENS_TO_DB = True

# Request additional Google API scopes
# Default: ["openid", "email", "profile"]
GOOGLE_OAUTH_SCOPES = [
    "openid",
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/userinfo.profile",
    # "https://www.googleapis.com/auth/calendar",  # Add if needed
]

Google Cloud Setup

For Development:

  1. Go to Google Cloud Console
  2. Create a project
  3. Go to Google Auth Platform
  4. Navigate to Clients > +Create Client

For Development use:

  • Application type: Web application
  • Name: Django Googler Dev
  • Authorized redirect URIs:
    • http://localhost:8000/api/auth/google/callback/
    • http://localhost:8000/auth/google/callback/ (frontend handler for Django-based frontend)
    • http://localhost:3000/auth/google/callback/ (frontend handler for React, Next.js or Vue)
    • Any others you might need during development

For Production use:

  • Application type: Web application
  • Name: Django Googler Prod
  • Redirect URIs:
    • https://yourdomain.com/api/auth/google/callback/
    • https://yourdomain.com/auth/google/callback/ (frontend handler for Django or Next.js/React/Vue frontend)
    • Any others you might need (adding more is fine especially if you have multiple frontend frameworks)

After you configure it, click Create and for each environment (prod/dev) grab:

  • Client ID (such as django-googler-dev.apps.googleusercontent.com and django-googler-prod.apps.googleusercontent.com)
  • Client Secret

For dev, update your .env file with:

GOOGLE_OAUTH_CLIENT_ID=django-googler-dev.apps.googleusercontent.com
GOOGLE_OAUTH_CLIENT_SECRET=your-dev-client-secret

For prod, update your runtime secrets with:

GOOGLE_OAUTH_CLIENT_ID=django-googler-prod.apps.googleusercontent.com
GOOGLE_OAUTH_CLIENT_SECRET=your-prod-client-secret

Making Google API Calls

If your backend needs to call Google APIs on behalf of users:

from django_googler.services import GoogleOAuthService


def my_view(request):
    # Get valid access token (auto-refreshes if expired)
    access_token, expiry = GoogleOAuthService.get_valid_token(request.user)

    if access_token:
        import requests

        headers = {"Authorization": f"Bearer {access_token}"}
        response = requests.get(
            "https://www.googleapis.com/calendar/v3/calendars/primary/events",
            headers=headers,
        )
        return response.json()

Using Django Views (Instead of API)

If you prefer browser redirects over API calls:

# urls.py
urlpatterns = [
    path("auth/", include("django_googler.urls.default")),
]

Then in your template:

<a href="{% url 'django_googler:google-login' %}?next=/dashboard/">
    Sign in with Google
</a>

Users will be redirected to Google and back, then logged into Django's session.

Architecture

  • Views - Handle OAuth flow and return JWT tokens
  • Services - Business logic for OAuth, users, and tokens
  • Models - Store Google OAuth tokens in database

License

MIT License

Support

GitHub Issues

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_googler-0.0.17.tar.gz (63.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_googler-0.0.17-py3-none-any.whl (34.1 kB view details)

Uploaded Python 3

File details

Details for the file django_googler-0.0.17.tar.gz.

File metadata

  • Download URL: django_googler-0.0.17.tar.gz
  • Upload date:
  • Size: 63.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for django_googler-0.0.17.tar.gz
Algorithm Hash digest
SHA256 417a3c7e79652e20b17bb58e42989b01bc91f3cf2d02ac3aa1c1a5e3c42f8fb4
MD5 4b4a29cc80eec5add1adace716d3c5dd
BLAKE2b-256 82cae25c769dfd6df1e346178e916a439c89ae9b9912a612fbf6c3d5f2b93920

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_googler-0.0.17.tar.gz:

Publisher: main.yaml on jmitchel3/django-googler

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_googler-0.0.17-py3-none-any.whl.

File metadata

File hashes

Hashes for django_googler-0.0.17-py3-none-any.whl
Algorithm Hash digest
SHA256 ec2de07af72997703c4411466a5e711bd9c5fe62f11466bb250fdeaf34d115d0
MD5 18ce48748c306498e9ada3ceededcb8e
BLAKE2b-256 c54588cbaaef6f7c6f156f16485c1ee4adf63b16734ee76b2bc90d9e2fbecf3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_googler-0.0.17-py3-none-any.whl:

Publisher: main.yaml on jmitchel3/django-googler

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page