使用 Next-auth 实现 Google 和 GitHub 社交登录

Next.jsAuthenticationOAuthTypeScript
Share on:

nextjs中集成github和google登录已经成为一种标配功能。本文将介绍如何在 Next.js 13+ 项目中使用 Next-auth 实现 Google 和 GitHub 的社交登录功能。

前置准备

首先,我们需要在 Google 和 GitHub 平台上创建应用并获取必要的凭证:

Google OAuth 设置

  1. 访问 Google Cloud Console
  2. 创建新项目或选择现有项目
  3. 启用 OAuth2.0 API
  4. 创建凭证,获取 Client ID 和 Client Secret
  5. 设置回调的URL

Google Cloud Console 设置截图 Google Cloud Console 设置截图

GitHub OAuth 设置

  1. 访问 GitHub Developer Settings
  2. 点击 "New OAuth App"
  3. 填写应用信息,获取 Client ID 和 Client Secret

GitHub OAuth 设置截图

项目实现

1. 安装依赖

npm install next-auth

配置环境变量

创建 .env.local 文件:

NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key
GITHUB_ID=your-github-client-id
GITHUB_SECRET=your-github-client-secret
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret

类型定义

types/next-auth.d.ts 中定义 Next-auth 的类型扩展:

import NextAuth from "next-auth"
declare module "next-auth" {
  interface Session {
    user: {
      id?: string
      name?: string | null
      email?: string | null
      image?: string | null
      provider?: string
    }
  }
  interface User {
    id?: string
    name?: string
    email?: string
    image?: string | null
    provider?: string
  }
}
declare module "next-auth/jwt" {
  interface JWT {
    provider?: string
    picture?: string | null
  }
}

配置 Auth 路由

创建 app/api/auth/[...nextauth]/route.ts 文件:

import NextAuth, { AuthOptions } from "next-auth"
import GithubProvider from "next-auth/providers/github"
import GoogleProvider from "next-auth/providers/google"

const authOptions: AuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
      authorization: {
        params: {
          scope: 'openid email profile',
          prompt: "consent",
          access_type: "offline",
          response_type: "code"
        }
      }
    }),
    GithubProvider({
      clientId: process.env.GITHUB_ID!,
      clientSecret: process.env.GITHUB_SECRET!,
      authorization: {
        params: {
          scope: 'read:user user:email'
        }
      }
    }),
  ],
  callbacks: {
    async signIn({ user, account }) {
      if (account?.provider) {
        user.provider = account.provider
      }
      return true
    },
    async jwt({ token, account, user }) {
      if (user) {
        token.provider = user.provider
      }
      return token
    },
    async session({ session, token }) {
      if (session.user) {
        session.user.provider = token.provider
      }
      return session
    },
  }
}

const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }

配置 SessionProvider

app/[locale]/layout.tsx 中添加 SessionProvider:

import { SessionProvider } from "next-auth/react"
import type { Metadata } from 'next'
export const metadata: Metadata = {
  title: '应用名称',
  description: '应用描述',
}
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <SessionProvider>{children}</SessionProvider>
      </body>
    </html>
  )
}

实现登录按钮

创建 components/auth/social-buttons.tsx

'use client'
import { signIn } from "next-auth/react"
export function GoogleSignInButton() {
  return (
    <button
      onClick={() => signIn('google')}
      className="flex items-center gap-2 rounded-lg border p-2"
    >
      使用 Google 登录
    </button>
  )
}
export function GitHubSignInButton() {
  return (
    <button
      onClick={() => signIn('github')}
      className="flex items-center gap-2 rounded-lg border p-2"
    >
      使用 GitHub 登录
    </button>
  )
}

使用效果

登录按钮界面截图

登录成功截图

安全考虑

  1. 确保 NEXTAUTH_SECRET 使用强随机值
  2. 正确配置 OAuth 应用的回调 URL
  3. 限制必要的 scope 范围
  4. 在生产环境使用 HTTPS

常见问题

回调 URL 配置错误

  • 确保在 OAuth 提供商配置中正确设置回调 URL
  • 开发环境:http://localhost:3000/api/auth/callback/{provider}
  • 生产环境:https://yourdomain.com/api/auth/callback/{provider}

环境变量未正确加载

  • 检查 .env.local 文件是否存在
  • 确保变量名称正确
  • 重启开发服务器

类型错误

  • 确保正确配置 next-auth.d.ts
  • 检查 TypeScript 配置

总结

Next-auth 提供了一个强大而灵活的认证解决方案。通过本文的配置,我们实现了:

  • Google 和 GitHub 社交登录
  • 类型安全的认证流程
  • 用户会话管理
  • 安全的令牌处理

记住要始终关注安全性,并根据项目需求适当调整配置。

相关资源