Next15 + Prisma + Auth5 实战讲解

依赖包安装

Next 安装

bash 复制代码
npx create-next-app@latest

根据需要选择配置

js 复制代码
1 What is your project named? my-app
2 Would you like to use TypeScript? No / Yes
3 Would you like to use ESLint? No / Yes
4 Would you like to use Tailwind CSS? No / Yes
5 Would you like your code inside a `src/` directory? No / Yes
6 Would you like to use App Router? (recommended) No / Yes
7 Would you like to use Turbopack for `next dev`?  No / Yes
8 Would you like to customize the import alias (`@/*` by default)? No / Yes
9 What import alias would you like configured? @/*

Prisma 安装

  • 项目使用版本为6.2.1
bash 复制代码
yarn add prisma@6.2.1 @prisma/client@6.2.1
  • 初始化
bash 复制代码
npx prisma init
npx prisma generate
  • 其他开发依赖
bash 复制代码
yarn add kysely

Auth 安装

  • install
bash 复制代码
yarn add next-auth@beta
  • auth secret 生成
  1. OpenSSL 命令行生成
bash 复制代码
openssl rand -base64 32  
  1. auth CLI
bash 复制代码
npx auth secret

Auth配置

  1. 例如Github登录, 就要先创建 GITHUB_ID 和 GITHUB_SECRET
  2. 在 .env.development 文件中放入环境变量
js 复制代码
NEXTAUTH_SECRET = 上面生成的 auth-secret
GOOGLE_CLIENT_ID = ****
GOOGLE_CLIENT_SECRET = ****
NEXTAUTH_URL = http://localhost:3000
GITHUB_ID = ****
GITHUB_SECRET = ****

根目录创建auth.ts, 并写入, 以下是完整auth代码

ts 复制代码
import NextAuth from 'next-auth'
import CredentialsProvider from "next-auth/providers/credentials";
import { findUser } from "libs/server_utils"
import Google from "next-auth/providers/google";
import GitHub from "next-auth/providers/github";

export const { handlers, signIn, signOut, auth } = NextAuth({
  secret: process.env.NEXTAUTH_SECRET,
  debug: true, // 启用调试模式
  logger: {
    error(error: unknown) {
      console.error("Auth Error:", error);
    },
  },
  providers: [
    // google登录
    Google({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    // github登录
    GitHub({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
    CredentialsProvider({
      name: 'Credentials',
      // 定义用户名和密码参数
      credentials: {
        username: { label: "Username" },
        password: { label: "Password", type: "password" },
      },
      authorize: async (credentials) => {
        if (!credentials || !credentials.username || !credentials.password) {
          return null;
        }
        // 检查用户是否存在, 结合prisma数据库操作
        const user = await findUser({
          username: credentials.username as string,
          password: credentials.password as string
        })
        if (!user || user.code == 500) {
          return null;
        }
        return user;
      }
    })
  ],
  session: { strategy: "jwt" },
  pages: {
    signIn: '/login'
  },
  callbacks: {
    async authorized({ request, auth }) {
      const url = request.nextUrl
      const user = auth?.user;
      if (url.pathname.startsWith('/admin') && !user) {
        return false
      }
      return true
    },
    jwt: async ({ token, user }) => {
      if ((user as { username?: string })?.username) {
        token.username = (user as { username: string }).username;
      }
      return token
    },
    session({ session, token }) {
      console.log("session=", session)
      console.log("token=", token)
      session.user = {
        id: token.sub as string,
        name: token.username as string || token.name,
        email: token.email as string,
        image: token.picture,
        emailVerified: null,
      };
      return session;
    },
  }
})

用户密码登录(Credentials)

  • 登录页面
  • 部分代码示例
ts 复制代码
import { signIn } from "next-auth/react";
const submitFormData = async (e: FormEvent<HTMLFormElement>) => {
  e.preventDefault();
  const result = await signIn("credentials", {
    username: formData.username,
    password: formData.password,
    redirect: false,
  });
  if (result?.error) {
    toast.warning(result.error)
    return;
  }
  if (result?.ok) {
    redirect("/")
  }
}
  • 登录成功

Google登录

  • GOOGLE_CLIENT_ID 创建

创建GoogleAuth应用

  • 创建完成后,写入环境变量即可
  • 示例代码
ts 复制代码
const handleLogin = async () => {
    try {
      const res = await signIn("google");
    } catch (error) {
      console.error("登录失败:", error);
    }
  };

GitHub登录

  • GITHUB_ID 创建

创建 GitHub OAuth 应用

  • 创建完成后,写入环境变量即可

  • 示例代码

ts 复制代码
<Button variant="outline" className="w-full cursor-pointer" onClick={() => signIn("github", { callbackUrl: "/home" })}>
  <GitHubLogoIcon />
  <span className="sr-only">Login with GitHub</span>
</Button>

Auth登录成功

如果想对开发细节进一步了解, 请访问 仓库链接

如果对你有帮助, 请点赞鼓励下

相关推荐
阿里巴啦11 小时前
React + Three.js + R3F + Vite 实战:可交互的三维粒子化展厅
react.js·three.js·粒子化·drei·postprocessing·三维粒子化
[seven]11 小时前
React Router TypeScript 路由详解:嵌套路由与导航钩子进阶指南
前端·react.js·typescript
程序员爱钓鱼12 小时前
Node.js 编程实战:数据库连接池与性能优化
javascript·后端·node.js
程序员爱钓鱼13 小时前
Node.js 编程实战:Redis缓存与消息队列实践
后端·面试·node.js
San3013 小时前
现代前端工程化实战:从 Vite 到 React Router demo的构建之旅
react.js·前端框架·vite
用户479492835691514 小时前
node_modules 太胖?用 Node.js 原生功能给依赖做一次大扫除
前端·后端·node.js
Qinana15 小时前
从零开始实现 GitHub 仓库导航器(Windows 实操版)
react.js·前端框架·vite
南山安15 小时前
React学习:Vite+React 基础架构分析
javascript·react.js·面试
一只叫煤球的猫15 小时前
我做了一个“慢慢来”的开源任务管理工具:蜗牛待办(React + Supabase + Tauri)
前端·react.js·程序员