Next.js + NextAuth 实现 GitHub 登录功能
🚀 Next.js + NextAuth 实现 GitHub 登录功能全记录
最近给我的博客系统接入了 GitHub 登录,顺利实现了用户通过 GitHub 授权快速登录的功能。本文记录完整的实现步骤和踩坑经历,方便自己复盘,也希望能帮到你。
🧱 技术栈简介
Next.js 15(使用 App Router)
next-auth(用于实现 OAuth)
GitHub OAuth App(作为第三方登录提供者)
TypeORM + MySQL(作为用户数据存储)
🪜 步骤一:配置 GitHub OAuth App
前往 GitHub 开发者设置 创建一个新的 OAuth App:
应用名称:随便起一个
Homepage URL:
http://localhost:3000
Authorization callback URL:
http://localhost:3000/api/auth/callback/github
创建完成后会得到:
Client ID
Client Secret
把这两个值放入 .env.local
文件中:
GITHUB_CLIENT_ID=your_client_id
GITHUB_CLIENT_SECRET=your_client_secret
🪜 步骤二:配置 NextAuth
在 app/api/auth/[...nextauth]/route.ts
中设置 next-auth
配置:
// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth';
import GitHubProvider from 'next-auth/providers/github';
export const authOptions = {
providers: [
GitHubProvider({
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
}),
],
callbacks: {
async signIn({ user, account }) {
// 你可以在这里将 GitHub 用户信息保存到数据库
if (account.provider === 'github') {
console.log('GitHub 用户信息:', user);
}
return true;
},
async jwt({ token, user }) {
if (user) token.githubId = user.id;
return token;
},
async session({ session, token }) {
if (token?.githubId) session.user.id = token.githubId;
return session;
},
},
};
const handler = NextAuth(authOptions);
export const GET = handler;
export const POST = handler;
⚠️ 注意事项:
使用 App Router 的 API Routes 必须导出
GET
和POST
方法,不能用默认导出。路由应为
/api/auth/[...nextauth]/route.ts
。
🪜 步骤三:前端调用登录
在登录组件中使用 signIn('github')
触发 GitHub 登录:
import { signIn } from 'next-auth/react';
const githubLogin = () => {
signIn('github', {
callbackUrl: '/', // 登录成功后的跳转地址
});
};
常见误区
如果你写了
redirect: false
,GitHub 页面不会跳转。第一次登录成功后,如果未退出,再次点按钮不会跳转,因为 next-auth 会判断已登录。
💥 踩坑记录
❌ 登录后不跳转 GitHub
原因:使用了 signIn('github', { redirect: false })
,这种方式适合“弹窗登录”或静默获取 session,不适合 OAuth 跳转。
✅ 修复:直接用 signIn('github', { callbackUrl: '/' })
即可。
🔐 登录后保存用户信息(可选)
你可以在 signIn
回调里将 GitHub 用户信息写入数据库,比如结合你原来的手机号登录逻辑,添加一个 identity_type = 'github'
的用户认证记录:
async signIn({ user, account }) {
if (account.provider === 'github') {
const db = AppDataSource;
if (!db.isInitialized) await db.initialize();
const userRepo = db.getRepository(Users);
const userAuthRepo = db.getRepository(UserAuths);
// 检查是否已经注册
let userAuth = await userAuthRepo.findOne({
where: {
identity_type: 'github',
identifier: account.providerAccountId, // GitHub 的 user id
},
});
if (!userAuth) {
// 创建用户
const newUser = userRepo.create({
nickname: user.name || user.login,
avatar: user.image || '/default-avatar.png',
});
const savedUser = await userRepo.save(newUser);
const newUserAuth = userAuthRepo.create({
user_id: savedUser.id,
identity_type: 'github',
identifier: account.providerAccountId,
credential: '', // 不需要密码
});
await userAuthRepo.save(newUserAuth);
}
}
return true;
}
✅ 总结
GitHub 登录在 Next.js + NextAuth 中配置其实非常顺滑,只要注意几点:
App Router 要显式导出
GET/POST
登录跳转要用
signIn('github', { callbackUrl })
GitHub 回调 URL 必须精确匹配 OAuth App 设置
登录成功后按需存入数据库
有问题欢迎留言讨论!如果你想了解如何用 session
驱动头像/昵称显示,也可以看我另一篇笔记「Next.js + Zustand 实现登录用户信息共享」。