Back to Shorts

Workflow

GitHub OAuth Flow, Framework Agnostic

GitHub OAuth is not tied to a specific framework. Whether you use Laravel, Express, Django, Spring Boot, Next.js, Rails, or Go, the main flow is still the sa...

2 views3 min read
Workflow

GitHub OAuth is not tied to a specific framework.

Whether you use Laravel, Express, Django, Spring Boot, Next.js, Rails, or Go, the main flow is still the same.

The implementation syntax may be different, but the authentication concept does not change.

1. Create OAuth App on GitHub
2. Redirect user to GitHub
3. GitHub redirects back with code
4. Backend exchanges code for access token
5. Backend gets GitHub user profile
6. App creates its own session

1. Register OAuth App

First, create an OAuth App from GitHub Developer Settings.

GitHub
→ Settings
→ Developer settings
→ OAuth Apps
→ New OAuth App

Set the callback URL based on your application.

https://yourdomain.com/auth/github/callback

For local development:

http://localhost:3000/auth/github/callback

After registering the app, GitHub gives you:

GITHUB_CLIENT_ID
GITHUB_CLIENT_SECRET

The client_id is public enough to be used in the authorization URL.

The client_secret must stay on the backend.


2. Redirect User to GitHub

When the user clicks “Login with GitHub”, your app redirects them to this URL:

https://github.com/login/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=YOUR_CALLBACK_URL
  &scope=read:user user:email
  &state=RANDOM_STATE

Example concept:

GET /auth/github

Generate random state
Save state temporarily
Redirect user to GitHub authorization URL

The state value is used to verify that the callback really belongs to the login request started by your app.


3. GitHub Redirects Back to Your App

After the user approves the login, GitHub redirects back to your callback URL.

GET /auth/github/callback?code=abc123&state=random_state

At this point, your app receives two important values:

code  = temporary code from GitHub
state = value used for request validation

Before continuing, compare the returned state with the one you saved earlier.

If state is invalid:
  reject the request

If state is valid:
  continue the login process

4. Exchange Code for Access Token

The code is not the final token.

Your backend must exchange it with GitHub.

POST https://github.com/login/oauth/access_token

Send:

client_id
client_secret
code
redirect_uri

Conceptually:

Backend sends code + client_secret to GitHub
GitHub returns access_token

This step must happen on the backend because it uses client_secret.

Never do this from frontend code.


5. Get GitHub User Profile

After receiving the GitHub access token, use it to call GitHub API.

GET https://api.github.com/user
Authorization: Bearer GITHUB_ACCESS_TOKEN

This returns basic GitHub user data such as:

id
login
name
avatar_url
email

Sometimes email can be null, so you may need to request:

GET https://api.github.com/user/emails

That is why many implementations request this scope:

read:user user:email

6. Find or Create User in Your Database

After getting the GitHub profile, your app should check whether the user already exists.

Find user by github_id

If user exists:
  update profile data if needed

If user does not exist:
  create new user

Example database fields:

id
github_id
email
name
username
avatar_url
role
created_at
updated_at

The most important field is:

github_id

Because GitHub username or email can change, but GitHub ID is more stable for identifying the account.


7. Create Your Own App Session

Do not use the GitHub access token as your main application session.

GitHub token is for accessing GitHub API.

Your app still needs its own session.

GitHub token → used to verify GitHub identity
App session  → used to login into your own app

Your app can create session using:

HTTP-only cookie
server-side session
JWT access token
refresh token

The idea is the same in any framework:

Create app session for user_id
Redirect user to dashboard

8. Protect Private Pages or APIs

After login is complete, your app should protect private routes.

Request comes in
Check app session
Find user from database
Allow or reject access

For example:

GET /dashboard
GET /api/me
GET /admin

These routes should not depend directly on GitHub OAuth anymore.

They should depend on your own app session.


Final Flow

User clicks Login with GitHub
↓
App redirects user to GitHub
↓
User approves login
↓
GitHub redirects back with code
↓
Backend exchanges code for access token
↓
Backend gets GitHub profile
↓
App finds or creates user
↓
App creates its own session
↓
User is logged in

The key mindset is:

OAuth is only for identity verification.
Your application still owns the session.

That is why this flow can be implemented in any backend framework.

The route syntax may change, but the architecture stays the same.

Helpful short? Tap like.

1

Comments

Join the discussion for this short.

GU

Join the discussion

Sign in first, then write a comment or reply to an existing thread.

Login required

Sign in with GitHub to start a new comment. After that, this area will become active for writing.

Your GitHub identity will be used for comment attribution.

Readers need to sign in with GitHub before they can post a comment or reply.
Loading comments...

Arya Dipanegara

Personal developer website for writing, projects, short notes, and practical software work.

Stay in touch

No newsletter flow here. Email works best for project ideas, collaborations, or quick questions.

Email me

© 2026 Arya Dipanegara. All rights reserved.