设置项目
首先,通过以下命令在终端中创建 Next.js 项目:
npx create-next-app@latest
选择以下配置:
- 项目名称
- 使用 TypeScript
- 使用 ESLint
- 使用 Tailwind CSS
- 使用
src/
目录 - 使用 App Router
- 自定义默认导入别名 (@/*)
安装 NextAuth.js
在项目设置完成后,通过 npm 安装 NextAuth.js:
npm install next-auth
创建文件夹和文件
在 app
目录中创建以下文件夹和 route.ts
文件:
api/auth/[...nextauth]/route.ts
在 app
目录中创建 components
文件夹,并在根目录(与 package.json
文件同级)创建 .env
文件。
目录结构如下:
my-next-app
│
├── app
│ ├── api
│ │ └── auth
│ │ └── [...nextauth]
│ │ └── route.ts
│ └── components
├── .env
├── package.json
...
设置环境变量
在 .env
文件中添加以下内容:
NEXTAUTH_SECRET=98E3B2CC28F61492C6934531C828C
NEXTAUTH_URL=http://localhost:3000/
NEXTAUTH_SECRET
是用于哈希令牌、签名/加密 Cookie 和生成加密密钥的随机字符串。NEXTAUTH_URL
是用户登录后的重定向路径。
配置 route.ts
在 app/api/auth/[...nextauth]/route.ts
文件中添加以下代码:
import NextAuth from "next-auth"; import GithubProvider from "next-auth/providers/github"; import GoogleProvider from "next-auth/providers/google"; const handler = NextAuth({ providers: [ GithubProvider({ clientId: process.env.GITHUB_ID as string, clientSecret: process.env.GITHUB_SECRET as string, }), GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID as string, clientSecret: process.env.GOOGLE_CLIENT_SECRET as string, }) ] }); export { handler as GET, handler as POST };
获取 GitHub 和 Google 的 ClientID 和 ClientSecret
GitHub
- 登录 GitHub
- 点击个人资料图片,选择
Settings
- 滚动到
Developer settings
- 选择
Oauth Apps
- 点击
Register a new application
- 填写应用名称、主页 URL 和授权回调 URL,然后点击
Register application
- 复制 Client ID 和生成的 Client Secret,并在
.env
文件中添加以下内容:
GITHUB_ID=<your clientID>
GITHUB_SECRET=<your clientSecret>
- 前往 Google Cloud Console
- 选择项目并获取 Client ID 和 Client Secret,添加到
.env
文件中:
GOOGLE_CLIENT_ID=<your clientID>
GOOGLE_CLIENT_SECRET=<your clientSecret>
创建 SessionWrapper 组件
在 components
文件夹中创建 SessionWrapper.tsx
文件:
"use client"; import { SessionProvider } from "next-auth/react"; import React from 'react'; const SessionWrapper = ({children}: {children: React.ReactNode}) => { return ( <SessionProvider>{children}</SessionProvider> ) } export default SessionWrapper;
在 layout.tsx 中使用 SessionWrapper
编辑 layout.tsx
文件:
import type { Metadata } from 'next'; import { Inter } from 'next/font/google'; import './globals.css'; import SessionWrapper from './components/SessionWrapper'; const inter = Inter({ subsets: ['latin'] }); export const metadata: Metadata = { title: 'Create Next App', description: 'Generated by create next app', }; export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <SessionWrapper> <html lang="en"> <body className={inter.className}>{children}</body> </html> </SessionWrapper> ); }
在 page.tsx 文件中添加登录/注销功能
编辑 page.tsx
文件:
"use client"; import { useSession, signIn, signOut } from "next-auth/react"; import Image from "next/image"; export default function Home() { const { data: session } = useSession(); if (session) { return ( <div className="w-full h-screen flex flex-col justify-center items-center"> <div className="w-44 h-44 relative mb-4"> <Image src={session.user?.image as string} fill alt="" className="object-cover rounded-full" /> </div> <p className="text-2xl mb-2">Welcome <span className="font-bold">{session.user?.name}</span>. Signed In As</p> <p className="font-bold mb-4">{session.user?.email}</p> <button className="bg-red-600 py-2 px-6 rounded-md" onClick={() => signOut()}>Sign out</button> </div> ) } return ( <div className="w-full h-screen flex flex-col justify-center items-center"> <p className="text-2xl mb-2">Not Signed In</p> <button className="bg-blue-600 py-2 px-6 rounded-md mb-2" onClick={() => signIn('google')}>Sign in with google</button> <button className="bg-none border-gray-300 border py-2 px-6 rounded-md mb-2" onClick={() => signIn('github')}>Sign in with github</button> </div> ) }
配置 next.config.js
编辑根目录下的 next.config.js
文件以允许加载来自远程主机的图像:
/** @type {import('next').NextConfig} */ const nextConfig = { images: { remotePatterns: [ { protocol: 'https', hostname: 'lh3.googleusercontent.com', }, { protocol: 'https', hostname: 'avatars.githubusercontent.com', }, ], }, }; module.exports = nextConfig;
现在,你已经成功在 Next.js 14 中配置了 NextAuth.js 并实现了身份验证功能。