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 [email protected] @prisma/[email protected]
  • 初始化
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登录成功

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

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

相关推荐
穗余5 小时前
NodeJS全栈开发面试题讲解——P5前端能力(React/Vue + API调用)
javascript·vue.js·react.js
IT瘾君6 小时前
JavaWeb:前端工程化-ElementPlus
前端·elementui·node.js·vue
早知道不学Java了6 小时前
chromedriver 下载失败
前端·vue.js·react.js·npm·node.js
哼唧唧_7 小时前
使用 React Native 开发鸿蒙运动健康类应用的高频易错点总结
react native·react.js·harmonyos·harmony os5·运动健康
EndingCoder8 小时前
React从基础入门到高级实战:React 高级主题 - React 微前端实践:构建可扩展的大型应用
前端·javascript·react.js·前端框架·状态模式
贩卖纯净水.9 小时前
Webpack搭建本地服务器
前端·webpack·node.js
树獭叔叔9 小时前
从零开始Node之旅 —— 事件模型
后端·node.js
xd000029 小时前
3. 简述node.js特性与底层原理
node.js
盼儿哥9 小时前
123网盘SDK-npm包已发布
前端·npm·node.js
itslife10 小时前
fiber 节点与 FiberRootNode - HostRootFiber
前端·react.js