Next-Auth 认证系统:用户与管理员双角色登录配置

概述

本文档介绍了如何使用 Next-Auth 配置一个同时支持普通用户和管理员用户登录的认证系统。

基本配置

首先,我们需要设置 Next-Auth 的基本配置,包括提供者、回调函数和页面路由。

import type { NextAuthConfig } from 'next-auth'
import type { User } from 'next-auth'
import Credentials from 'next-auth/providers/credentials'
import { LoginSchema } from '@/types/auth'
import { prisma } from '@/lib/prisma'
import bcrypt from 'bcryptjs'export const authOptions = {providers: [// 配置提供者],callbacks: {// 配置回调函数},pages: {// 配置页面路由},
} satisfies NextAuthConfig

配置认证提供者

需要配置两个 Credentials 提供者,分别用于普通用户和管理员用户的登录。

providers: [Credentials({id: 'user-login', // 普通用户登录name: 'User Credentials',async authorize(credentials) {try {const validatedFields = LoginSchema.safeParse(credentials)if (!validatedFields.success) return nullconst { email, password } = validatedFields.dataconst user = await prisma.user.findUnique({where: { email },select: {id: true,email: true,password: true,username: true,avatar_url: true,},})if (!user?.password) return nullconst passwordsMatch = await bcrypt.compare(password, user.password)if (!passwordsMatch) return nullreturn {id: user.id,email: user.email,username: user.username || user.email?.split('@')[0] || '',avatar_url: user.avatar_url || '',role: 'user', // 添加角色标识}} catch (error) {console.error('User authorization error:', error)return null}},}),Credentials({id: 'admin-login', // 管理员登录name: 'Admin Credentials',async authorize(credentials) {try {const validatedFields = LoginSchema.safeParse(credentials)if (!validatedFields.success) return nullconst { email, password } = validatedFields.dataconst admin = await prisma.adminUser.findUnique({where: { email },select: {id: true,email: true,password: true,username: true,avatar_url: true,role: true,},})if (!admin?.password) return nullconst passwordsMatch = await bcrypt.compare(password, admin.password)if (!passwordsMatch) return nullreturn {id: admin.id,email: admin.email,username: admin.username,avatar_url: admin.avatar_url || '',role: 'admin', // 添加角色标识}} catch (error) {console.error('Admin authorization error:', error)return null}},}),
],

配置回调函数

回调函数用于处理会话和 JWT 令牌的自定义逻辑。

callbacks: {async session({ session, token }) {if (session.user) {session.user.username = token.username as stringsession.user.id = token.sub as stringsession.user.avatar_url = token.avatar_url as stringsession.user.role = token.role as string // 添加角色}return session},async jwt({ token, user }) {if (user) {token.username = user.usernametoken.sub = user.idtoken.avatar_url = user.avatar_urltoken.role = user.role // 添加角色}return token},
},

配置页面路由

配置自定义的登录页面和错误页面。

pages: {signIn: '/login', // 普通用户登录页error: '/auth/error', // 错误页面
},

扩展 Session 类型

为了在 TypeScript 中正确识别自定义的会话属性,我们需要扩展 Next-Auth 的类型定义。

// types/next-auth.d.ts
import { DefaultSession } from "next-auth"declare module "next-auth" {interface Session {user: {id: stringusername: stringavatar_url: stringrole: string} & DefaultSession["user"]}interface User {id: stringusername: stringavatar_url: stringrole: string}
}

区分用户和管理员

如果需要在会话中明确区分用户和管理员,可以修改 session 回调函数:

async session({ session, token }) {if (session.user) {session.user.username = token.username as stringsession.user.id = token.sub as stringsession.user.avatar_url = token.avatar_url as stringsession.user.role = token.role as string}// 添加区分的用户和管理员对象if (token.role === 'admin') {session.admin = {id: token.sub as string,email: session.user?.email,username: token.username as string,avatar_url: token.avatar_url as string,role: 'admin'}} else {session.admin = null // 如果不是管理员,设置为 null}return session
},

同时更新类型定义:

// types/next-auth.d.ts
interface Session {user: {id: stringusername: stringavatar_url: stringrole: string} & DefaultSession["user"]admin: {id: stringemail?: string | nullusername: stringavatar_url: stringrole: string} | null
}

使用方式

在组件中使用会话信息:

import { useSession } from "next-auth/react"function MyComponent() {const { data: session } = useSession()// 检查是否是管理员if (session?.user?.role === 'admin') {// 管理员逻辑} else {// 普通用户逻辑}// 或者使用扩展的 admin 对象if (session?.admin) {// 管理员逻辑} else {// 普通用户逻辑}
}

登录方式

在登录表单中,可以通过指定 providerId 来选择使用哪个认证提供者:

import { signIn } from "next-auth/react"// 普通用户登录
signIn("user-login", { email, password,redirect: true,callbackUrl: "/dashboard"
})// 管理员登录
signIn("admin-login", { email, password,redirect: true,callbackUrl: "/admin/dashboard"
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/898653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS配置永久静态IP

在 CentOS 6 中,配置永久 IP 地址需要修改网络配置文件。以下是详细步骤: 1. 找到网卡名称 首先,确定你需要配置 IP 的网卡名称,通常是 eth0 或类似的名称。 运行以下命令查看网卡信息: bash ifconfig或者&#xf…

springboot Actuator 指标分析

http.server.requests HTTP 接口性能瓶颈 http.server.requests.max system.cpu.usage 代码热点分析或横向扩容 核心接口性能指标,包含以下维度: count:请求总数 max/sum:最大及总响应时间 status:HTTP 状态码分布&a…

在K8S中挂载 Secret 到 Pod

在 Kubernetes 里,把 Secret 挂载到 Pod 中有两种主要方式:作为卷挂载和作为环境变量挂载。下面为你提供相应的代码示例。 作为卷挂载 Secret 将 Secret 作为卷挂载到 Pod 时,Secret 的每个键会成为挂载目录下的一个文件,文件内…

mac npm run dev报错 error:0308010C:digital envelope routines::unsupported

并且提示 Unsupported engine { npm WARN EBADENGINE package: achrinza/node-ipc9.2.2, npm WARN EBADENGINE required: { node: 8 || 10 || 12 || 14 || 16 || 17 }, npm WARN EBADENGINE current: { node: v18.18.0, npm: 9.8.1 } npm WARN EBADENGINE } package.jso…

「宇树科技」13家核心零部件供应商梳理!

2025年2月6日,摩根士丹利(Morgan Stanley)发布最新人形机器人研报:Humanoid 100: Mapping the Humanoid Robot Value Chain(人形机器人100:全球人形机器人产业链梳理)。 2025年2月20日&#xf…

MySQL 性能优化方向

MySQL 性能优化是一个系统性的工作,涉及数据库设计、查询优化、索引优化、硬件配置等多个方面。以下是 MySQL 性能优化的主要方向和具体优化方案: 一、数据库设计优化 1. 合理设计表结构 规范化设计:避免数据冗余,确保数据一致性。适度反规范化:在查询频繁的场景下,适当…

MyBatis plus详解

核心功能 代码生成器 它能够依据数据库表结构,自动生成涵盖实体类、Mapper 接口、Mapper XML 文件、Service 接口与实现类等在内的基础代码。开发人员只需简单配置数据库连接信息、表名以及生成代码的相关参数,即可快速生成符合项目规范的基础代码&…

背包问题——多重背包(C语言)

代码如下&#xff1a; #include<stdio.h>int knapsack(int weight[], int value[], int count[], int n, int capacity) {int* dp (int*)malloc(sizeof(int) * (capacity 1));for (int i 0; i < capacity; i){dp[i] 0;}for (int i 0; i < n; i)//核心代码{fo…

计算机技术系列博客——目录页(持续更新)

1.1 博客目录专栏 1.1.1 博客文章导航 计算机技术系列博客——目录页 1.1.2 网页资源整理 2.1 计算机科学理论 2.2 软件工程技术 2.2.1.1 编程语言 Java Java语言基础 (1) Java基础知识总结01——Java基础篇 (2) Java基础知识总结02——集合框架篇 (3) Java基础知识总结03—…

<项目> 主从Reactor模型的高并发服务器

目录 Reactor 概念 分类 单Reactor单线程 单Reactor多线程 多Reactor多线程 项目介绍 项目规划 模块关系 实现 TimerWheel -- 时间轮定时器 定时器系统调用 时间轮设计 通用类型Any Buffer Socket Channel Poller EventLoop&#xff08;核心&#xff09; eventfd 设计思路 …

车载以太网网络测试-20【传输层-DOIP协议-3】

1 摘要 本文继续对ISO 13400-2定义的节点管理报文进行介绍&#xff0c;主要对路由激活请求/响应报文以及在线检查请求/响应报文的作用、帧结构以及示例进行介绍。 上文回顾&#xff1a; 车载以太网网络测试-19【传输层-DOIP协议-2】 在进行详细介绍之前&#xff0c;还是先回顾…

Jvm运行时数据区有哪些

Jvm运行时数据区有哪些 程序计数器&#xff08;Program Counter Register&#xff09; 作用&#xff1a; 可以看作是当前线程所执行的字节码的行号指示器。在多线程环境下&#xff0c;每个线程都有自己独立的程序计数器&#xff0c;线程私有的&#xff0c;用于记录该线程正在执…

Compose 实践与探索十五 —— 自定义触摸

1、自定义触摸与一维滑动监测 之前我们在讲 Modifier 时讲过如下与手势检测相关的 Modifier&#xff1a; Modifier.clickable { } Modifier.combinedClickable { } Modifier.pointerInput {detectTapGestures { } }这里对以上内容就不再赘述了&#xff0c;直接去讲解更复杂的…

Python 中有哪些库可以帮助读取和操作 shapefile 文件?

Python操作Shapefile文件库推荐 1. PyShp (pyshp) 特点&#xff1a;纯Python实现&#xff0c;无外部依赖&#xff0c;轻量级&#xff0c;支持完整的Shapefile格式&#xff08;shp、dbf、shx&#xff09;读写。适用场景&#xff1a;基础读写、简单几何操作、文件格式转换。安装…

JSONPath 的介绍

JSONPath的起源 1. 起源背景 在讨论JSONPath的起源之前&#xff0c;让我们先了解JSONPath是什么。JSONPath 是一种查询语言&#xff0c;用于从JSON&#xff08;JavaScript Object Notation&#xff09;数据结构中提取数据。它允许开发者通过类似于XPath的表达式来定位JSON对象…

【CSS文字渐变动画】

CSS文字渐变动画 HTML代码CSS代码效果图 HTML代码 <div class"title"><h1>今天是春分</h1><p>正是春天到来的日子&#xff0c;花都开了&#xff0c;小鸟也飞回来了&#xff0c;大山也绿了起来&#xff0c;空气也有点嫩嫩的气息了</p>…

Bitcoin Thunderbolt 内测通道开启,加速比特币交易新时代

比特币作为全球领先的加密货币&#xff0c;一直占据着去中心化金融的核心地位。然而&#xff0c;随着比特币生态的不断扩展&#xff0c;其交易速度和扩容问题逐渐成为制约发展的关键瓶颈。为解决这一难题&#xff0c; 比特币雷电网络&#xff08;Bitcoin Thunderbolt&#xff0…

Postgresql无法连接问题汇总

一. 数据库服务未启动 ❌报错信息&#xff1a; [postgresk8s-node2 ~]$ psql psql: could not connect to server: No such file or directoryIs the server running locally and acceptingconnections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"…

软件工程之软件验证计划Software Verification Plan

个人主页&#xff1a;云纳星辰怀自在 座右铭&#xff1a;“所谓坚持&#xff0c;就是觉得还有希望&#xff01;” 本文为基于ISO26262软件验证计划模板&#xff0c;仅供参考。 软件验证计划&#xff0c;包括&#xff1a; 1. 软件需求验证计划 2. 软件架构设计验证计划 3. 软件单…

SpringBoot之如何集成SpringDoc最详细文档

文章目录 一、概念解释1、OpenAPI2、Swagger3、Springfox4、Springdoc5. 关系与区别 二、SpringDoc基本使用1、导包2、正常编写代码&#xff0c;不需要任何注解3、运行后访问下面的链接即可 三、SpringDoc进阶使用1、配置文档信息2、配置文档分组3、springdoc的配置参数**1. 基…