Complete Guide to Implementing GitHub and Google OAuth Authentication with Next.js — How to Achieve Smooth User Login
Introduction
In previous articles, after implementing the series of processes from account creation to login and logout, we implemented the following features that are operationally necessary for authentication:
- Checking whether an email address exists
- Password reset
- Two-factor authentication
Basically, the flow was to pass a token as a tool to verify the registered email address, and once identity verification was completed, perform the above processes. Although the implementation patterns are somewhat fixed, those who implemented each one locally with a fair amount of code probably found it quite time- and labor-intensive.
Implementing authentication features on your own inevitably takes a fair amount of time. When launching a new service, you often don’t have enough resources to build your own authentication features from scratch.
In such cases, it becomes effective to use OAuth and delegate authentication to external services.
This time, we’ll implement OAuth authentication using GitHub and Google as the authentication infrastructure.
Once your service becomes stable, it’s a good idea to implement email/password authentication as well to acquire more users. (So the articles I’ve introduced so far are not meaningless—rest assured.)
Goal of This Article
We will enable login via OAuth authentication using GitHub and Google as authentication providers.
When you click the GitHub or Google icon placed on the login screen, the OAuth consent screen will appear, and once you grant permission, you will be logged in and redirected to the settings screen.
For GitHub:
For Google:
About OAuth Authentication
Before we dive into the implementation, let’s briefly introduce OAuth authentication.
OAuth is a mechanism that allows online services to safely “grant other applications access to some of your information or functionality.” Put simply, it’s “a procedure that lets you grant only the necessary permissions without handing over your account credentials to other apps.”
For example, when you want to log in to the authentication tutorial web service we’re building in this article (hereafter, “authentication tutorial”) using your GitHub account, OAuth safely handles this process as follows:
- Log in to GitHub: When you choose to log in to the authentication tutorial with GitHub, the GitHub login screen is displayed. You enter your GitHub password there, but the authentication tutorial itself never sees this password.
- Request for permission: When logging in to the authentication tutorial via GitHub, the tutorial sends a request to GitHub like “Is it okay to access XX information?”. The scope of this permission is something you can configure, such as “profile information only” or “access to repositories,” etc.
- You decide whether to grant permission: GitHub then asks, “This app is trying to access XX. Do you allow it?” You choose whether to grant access.
- Token issuance: If you allow it, GitHub issues a key called a “token” to that service. Using this token, the service can access your account without directly receiving your password.
- Authentication tutorial uses the token to access: The authentication tutorial can then perform operations on your GitHub account within the allowed scope. As long as it has the token, it can perform permitted operations without needing your password.
From the authentication tutorial’s perspective, the requirement is simply to identify “who is currently accessing the service.” So it doesn’t matter whether that’s via GitHub, Google, Meta, X, or anything else. In this article, we’ll use GitHub and Google because they’re relatively easy to implement.
GitHub
Creating an OAuth App
If you already have a GitHub account, access the URL below and start creating an OAuth app.
Click your profile picture in the upper right corner of any GitHub page and click “Settings.”
In the left sidebar, click “Developer settings.”
In the left sidebar, click “OAuth Apps.”
If this is your first time visiting, you probably won’t see anything created here yet.
Click “New OAuth app” to create one.
You’ll need to fill in the following fields:
- Application name: To make it clear that this is for testing, use
nextjs-14-auth. - Homepage URL: Specify the top page of your Next.js app.
- Authorization callback URL: Specify the URL to which users will be redirected after authentication from GitHub.
Once the OAuth app is created, you should see a screen like the one below.
Set the Client ID and Client secrets as environment variables.
GITHUB_CLIENT_ID : Client ID
GITHUB_CLIENT_SECRET : Client secrets
GITHUB_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxx
GITHUB_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Next, configure Auth.js so that it can treat GitHub as a provider.
+ import Github from 'next-auth/providers/github'
export default {
providers: [
+ Github({
+ clientId: process.env.GITHUB_CLIENT_ID,
+ clientSecret: process.env.GITHUB_CLIENT_SECRET,
+ }),
By configuring it this way, when a user chooses OAuth authentication with GitHub, they will be redirected to the GitHub OAuth app we just created, and once authentication succeeds, Auth.js will be able to exchange tokens with GitHub.
Storing Tokens
Once token exchange is possible, prepare the schema so you can store tokens in the database.
Create a new model called Account and associate it with the already existing User model.
model User {
id String @id @default(cuid())
- name String
+ name String?
- email String @unique
+ email String? @unique
emailVerified DateTime?
+ image String?
- password String
+ password String?
+ accounts Account[]
}
+ model Account {
+ id String @id @default(cuid())
+ userId String
+ type String
+ provider String
+ providerAccountId String
+ refresh_token String? @db.Text
+ access_token String? @db.Text
+ expires_at Int?
+ token_type String?
+ scope String?
+ id_token String? @db.Text
+ session_state String?
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+ @@unique([provider, providerAccountId])
+ }
Up to now, the User model assumed email/password authentication, so fields like email, password, and name were required.
When we introduce OAuth authentication via GitHub, these fields may not be set, so we need to change them from required to optional.
For more details, refer to the documentation below:
Once the schema is ready, run the following commands to generate types and apply the schema to the database.
npx prisma generate
npx prisma db push
Implementing the UI
Finally, implement the process that runs when the user clicks the GitHub button.
This is handled in the /components/auth/social.tsx file, whose UI we already created in the article below:
+ import { signIn } from 'next-auth/react'
import { FaGithub } from 'react-icons/fa'
import { FcGoogle } from 'react-icons/fc'
import { Button } from '@/components/ui/button'
+ import { DEFAULT_LOGIN_REDIRECT } from '@/route'
export const Social = () => {
+ const onClick = (provider: 'google' | 'github') => {
+ signIn(provider, {
+ callbackUrl: DEFAULT_LOGIN_REDIRECT,
+ })
+ }
return (
<div className="flex w-full items-center gap-x-2">
(※some parts omitted)
<Button
size="lg"
className="w-full"
variant="outline"
+ onClick={() => onClick('github')}
>
<FaGithub className="size-5" />
</Button>
When the button with the GitHub icon is clicked, Auth.js’s signIn function is executed.
It assumes either GitHub or Google as the provider, and after authentication succeeds and token exchange is complete, the user is redirected to the page specified by DEFAULT_LOGIN_REDIRECT.
This value was configured in the article below:
Specifically, it points to http://localhost:3000/settings, so it’s set up to redirect the logged-in user to the settings page as the first page they see.
Verifying Operation
From the login screen, click the GitHub icon to transition to the GitHub OAuth app.
Click “Authorize” to return to the Next.js app and be redirected to the settings screen.
npx prisma migrate reset
Once OAuth authentication with GitHub is working, we’ll implement Google in a similar way.
Creating an OAuth App
First, create a new project in Google Cloud Platform.
Create a new project:
After selecting the project you created, click “APIs & Services” → “OAuth consent screen” in that order.
On the OAuth consent screen, set the User Type to “External.” (Since the connection is from a Next.js application, from Google Cloud’s perspective it is treated as an external application.)
Configure the App name and User support email.
As with GitHub, set the App name to nextjs-14-auth.
You don’t need to configure anything in this section.
We don’t need to configure Test users this time either, so click “SAVE AND CONTINUE” to create the consent screen.
If you see the screen below, the creation is complete.
Now that the consent screen is ready, we’ll issue an OAuth client ID.
Select “CREATE CREDENTIALS” → “OAuth client ID.”
Register the following:
Authorized JavaScript origins
http://localhost:3000
Authorized redirect URIs
http://localhost:3000/api/auth/callback/google
Once the OAuth client ID has been issued, check the Client ID and Client Secret.
As with GitHub, set the Client ID and Client Secret as environment variables.
GOOGLE_CLIENT_ID : Client ID
GOOGLE_CLIENT_SECRET : Client Secret
GOOGLE_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GOOGLE_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Next, configure Auth.js so that it can treat Google as a provider, along with GitHub.
import Github from 'next-auth/providers/github'
+ import Google from 'next-auth/providers/google'
export default {
providers: [
Github({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
}),
+ Google({
+ clientId: process.env.GOOGLE_CLIENT_ID,
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET,
+ }),
By configuring it this way, when a user chooses OAuth authentication with Google, they will be redirected to the Google OAuth app we just created, and once authentication succeeds, Auth.js will be able to exchange tokens with Google.
Implementing the UI
We already configured the database to store received tokens when we set up GitHub, so no additional database configuration is needed for Google.
All that remains is to implement the process that runs when the user clicks the Google icon button.
This is handled in the /components/auth/social.tsx file, whose UI we already created in the article below:
import { signIn } from 'next-auth/react'
import { FaGithub } from 'react-icons/fa'
import { FcGoogle } from 'react-icons/fc'
import { Button } from '@/components/ui/button'
import { DEFAULT_LOGIN_REDIRECT } from '@/route'
export const Social = () => {
const onClick = (provider: 'google' | 'github') => {
signIn(provider, {
callbackUrl: DEFAULT_LOGIN_REDIRECT,
})
}
return (
<div className="flex w-full items-center gap-x-2">
<Button
size="lg"
className="w-full"
variant="outline"
+ onClick={() => onClick('google')}
>
<FcGoogle className="size-5" />
</Button>
<Button
size="lg"
className="w-full"
variant="outline"
onClick={() => onClick('github')}
>
<FaGithub className="size-5" />
</Button>
</div>
)
Verifying Operation
From the login screen, click the Google icon to transition to the Google OAuth app.
Click “Next” on the “Sign in to nextjs-14-auth” screen to return to the Next.js app and be redirected to the settings screen.
npx prisma migrate reset
Conclusion
We created OAuth apps using GitHub and Google as authentication providers.
We then configured integration with the Next.js application, set up storing tokens in the database after receiving them, and implemented OAuth authentication.
Both GitHub and Google can be integrated with relatively simple configuration, and once you actually implement them, you may find it’s easier than expected.
By delegating user management to external services, you can avoid implementing a wide range of user-management features yourself and instead focus on more important features of your service.
I hope effectively leveraging these services will help you improve your development speed.
Questions about this article 📝
If you have any questions or feedback about the content, please feel free to contact us.Go to inquiry form
Related Articles
Complete Guide to Web Accessibility: From Automated Testing with Lighthouse / axe and Defining WCAG Criteria to Keyboard Operation and Screen Reader Support
2023/11/21Introduction to Automating Development Work: A Complete Guide to ETL (Python), Bots (Slack/Discord), CI/CD (GitHub Actions), and Monitoring (Sentry/Datadog)
2024/02/12Chat App (with Image/PDF Sending and Video Call Features)
2024/07/15CI/CD Strategies to Accelerate and Automate Your Development Flow: Leveraging Caching, Parallel Execution, and AI Reviews
2024/03/12Practical Component Design Guide with React × Tailwind CSS × Emotion: The Optimal Approach to Design Systems, State Management, and Reusability
2024/11/22Strengthening Dependency Security: Best Practices for Vulnerability Scanning, Automatic Updates, and OSS License Management
2024/01/29Bringing a Go + Gin App Up to Production Quality: From Configuration and Structure to CI
2023/12/06Management Dashboard Features (Graph Display, Data Import)
2024/06/02














