Skip to content

Tutorial OAuth Login

level09 edited this page Dec 30, 2025 · 1 revision

Add Google and GitHub Login

Enferno includes OAuth authentication out of the box. This tutorial shows how to enable it.

Time: ~15 minutes


What's Already Built

Enferno ships with complete OAuth support:

  • Google and GitHub login handlers (enferno/public/views.py)
  • OAuth model to link providers to users (enferno/user/models.py)
  • Automatic account creation for new OAuth users
  • Account linking for existing users with matching email

You just need to add your credentials.


Step 1: Get Google OAuth Credentials

  1. Go to Google Cloud Console
  2. Create a project (or select existing)
  3. Navigate to APIs & Services → Credentials
  4. Click Create Credentials → OAuth client ID
  5. Select Web application
  6. Add authorized redirect URI:
    • Development: http://localhost:5000/login/google/authorized
    • Production: https://yourdomain.com/login/google/authorized
  7. Copy the Client ID and Client Secret

Step 2: Get GitHub OAuth Credentials

  1. Go to GitHub Developer Settings
  2. Click New OAuth App
  3. Fill in:
    • Application name: Your app name
    • Homepage URL: http://localhost:5000 (or production URL)
    • Authorization callback URL: http://localhost:5000/login/github/authorized
  4. Click Register application
  5. Copy the Client ID and generate a Client Secret

Step 3: Configure Environment

Add to your .env file:

# Google OAuth
GOOGLE_AUTH_ENABLED=true
GOOGLE_OAUTH_CLIENT_ID=your_google_client_id
GOOGLE_OAUTH_CLIENT_SECRET=your_google_client_secret

# GitHub OAuth
GITHUB_AUTH_ENABLED=true
GITHUB_OAUTH_CLIENT_ID=your_github_client_id
GITHUB_OAUTH_CLIENT_SECRET=your_github_client_secret

Restart the server:

uv run flask run

Step 4: Test It

Visit http://localhost:5000/login and you should see:

  • "Sign in with Google" button
  • "Sign in with GitHub" button

Click either to test the flow.


How It Works

New users: OAuth creates an account automatically using email from the provider. Password is set to a random value with password_set=False so they can set one later.

Existing users: If a user with matching email exists, OAuth links to that account instead of creating a duplicate.

Multiple providers: Users can link multiple OAuth providers to one account.


Code Reference

The OAuth handling is in enferno/public/views.py:

@oauth_authorized.connect
def oauth_logged_in(blueprint, token):
    # Get user info from provider
    provider_data = get_oauth_user_data(blueprint)

    # Check if OAuth entry exists
    oauth = OAuth.query.filter_by(
        provider=blueprint.name,
        provider_user_id=user_id
    ).one_or_none()

    if oauth and oauth.user:
        # Existing OAuth user - log them in
        login_user(oauth.user)
    else:
        # Check for existing user with same email
        existing_user = User.query.filter_by(email=provider_data["email"]).first()
        if existing_user:
            # Link OAuth to existing account
            oauth.user = existing_user
        else:
            # Create new user
            user = create_oauth_user(provider_data, token, ip_address)
            oauth.user = user

Configuration is in enferno/settings.py:

GOOGLE_AUTH_ENABLED = os.environ.get("GOOGLE_AUTH_ENABLED", "False").lower() == "true"
GOOGLE_OAUTH_CLIENT_ID = os.environ.get("GOOGLE_OAUTH_CLIENT_ID")
GOOGLE_OAUTH_CLIENT_SECRET = os.environ.get("GOOGLE_OAUTH_CLIENT_SECRET")

GITHUB_AUTH_ENABLED = os.environ.get("GITHUB_AUTH_ENABLED", "False").lower() == "true"
GITHUB_OAUTH_CLIENT_ID = os.environ.get("GITHUB_OAUTH_CLIENT_ID")
GITHUB_OAUTH_CLIENT_SECRET = os.environ.get("GITHUB_OAUTH_CLIENT_SECRET")

Adding Another Provider

Prompt for AI assistant:

Add Twitter/X OAuth login following the same pattern as Google and GitHub. Add settings for TWITTER_AUTH_ENABLED, TWITTER_OAUTH_CLIENT_ID, TWITTER_OAUTH_CLIENT_SECRET. Register the blueprint in app.py and add the handler in public/views.py.

Flask-Dance supports many providers: Twitter, Facebook, Discord, LinkedIn, etc.


Troubleshooting

Issue Solution
"Authentication failed" Check credentials in .env match exactly
Redirect URI mismatch Ensure callback URL in provider console matches exactly
Buttons not showing Check *_AUTH_ENABLED=true is set
HTTPS errors locally Use HTTP for localhost, HTTPS for production

Production Notes

For production deployment with Ignite:

  1. Update OAuth callback URLs to use your domain with HTTPS
  2. Set environment variables on your server
  3. Ignite handles HTTPS automatically via Caddy

← Back to Tutorials