Blitz.js API中能否使用ctx.session.$create并写入数据库?
问题:Blitz.js API中能否使用ctx.session.$create并将会话数据写入数据库?
我正在Flutter项目中尝试集成Blitz.js登录API,已创建/api/auth/login.ts文件并编写了对应代码:
import { getAntiCSRFToken, getSession, SecurePassword } from "@blitzjs/auth" import { authenticateUser } from "app/auth/mutations/login" import { AuthenticationError } from "blitz" import db from "db" import { Role } from "types" const handler = async (req, res) => { const session = await getSession(req, res) const { email, password } = req.body if (req.method !== "POST" || !req.body.data || !session.userId) { res.status(401).json({ error: `Do not tamper with this route!` }) } else { console.log("Create a new session for the user") // Create a new session for the user //login const user = await authenticateUser(email, password) const user = await db.user.findFirst({ where: { email } }) if (!user) return res.json({ data: "Hello", email, password }) const result = await SecurePassword.verify(user.hashedPassword, password) const { hashedPassword, ...rest } = user await req.session.$create({ userId: user.id, role: user.role as Role }) res.json({ rest }) } export default handler
查阅Blitz.js官方文档后仍觉得内容不够清晰易懂,特此询问:能否在Blitz.js API中使用ctx.session.$create并将会话数据写入数据库?
可以的,而且Blitz.js的session.$create本身就会自动处理会话数据的持久化(包括写入数据库),不过你当前的代码存在几个关键问题需要修正:
- 重复声明
user变量:先调用authenticateUser(email, password)又重新查询数据库,完全没必要,authenticateUser已封装了用户查询与密码校验逻辑,直接用它返回的用户对象即可。 - 请求校验逻辑错误:
!session.userId的判断不合理,登录接口本身是给未登录用户调用的,此时session.userId本就不存在,会导致合法登录请求直接返回401。 - 未处理密码验证失败场景:调用
SecurePassword.verify后,未校验结果是否为SecurePassword.VALID,无法给用户返回正确的错误提示。 - 会话对象使用不一致:先通过
getSession获取了session变量,后续却用req.session.$create,应该保持统一使用session.$create。
修正后的代码示例
import { getSession } from "@blitzjs/auth" import { authenticateUser } from "app/auth/mutations/login" import { AuthenticationError } from "blitz" import { Role } from "types" const handler = async (req, res) => { // 仅允许POST请求 if (req.method !== "POST") { return res.status(405).json({ error: "仅支持POST请求" }) } const { email, password } = req.body // 校验请求参数完整性 if (!email || !password) { return res.status(400).json({ error: "邮箱和密码不能为空" }) } const session = await getSession(req, res) try { // 用内置的authenticateUser完成用户验证,自动处理密码校验和用户查询 const user = await authenticateUser({ email, password }) // 创建会话,Blitz会自动将加密后的会话数据写入数据库并设置Cookie await session.$create({ userId: user.id, role: user.role as Role }) // 返回脱敏后的用户信息 const { hashedPassword, ...userData } = user res.status(200).json(userData) } catch (error) { // 捕获验证错误,返回对应提示 if (error instanceof AuthenticationError) { return res.status(401).json({ error: "邮箱或密码错误" }) } res.status(500).json({ error: "服务器内部错误" }) } } export default handler
补充说明
Blitz.js的会话系统默认基于你配置的数据库适配器存储会话数据,调用session.$create时,框架会自动完成以下操作:
- 生成唯一会话ID
- 将会话数据(如
userId、role)加密后写入数据库的sessions表 - 在响应头中设置包含会话ID的Cookie,后续请求通过该Cookie识别用户会话
无需你手动编写数据库写入逻辑,Blitz已封装好这部分底层实现。
内容的提问来源于stack exchange,提问作者Aiman Almureish
相关产品推荐
相关产品推荐

