80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
import { NextResponse } from 'next/server'
|
|
import { prisma } from '@/lib/prisma' // 使用统一的prisma实例
|
|
import { compare } from 'bcryptjs'
|
|
import { z } from 'zod'
|
|
|
|
const loginSchema = z.object({
|
|
phone: z.string()
|
|
.min(11, '手机号必须是11位')
|
|
.max(11, '手机号必须是11位')
|
|
.regex(/^1[3-9]\d{9}$/, '请输入有效的手机号'),
|
|
password: z.string().min(6, '密码至少需要6个字符'),
|
|
})
|
|
|
|
export async function POST(request: Request) {
|
|
try {
|
|
const body = await request.json()
|
|
const { phone, password } = loginSchema.parse(body)
|
|
|
|
|
|
// 查找用户 - 使用正确的查询方式
|
|
const user = await prisma.user.findUnique({
|
|
where: {
|
|
phone: phone.trim() // 去除空格
|
|
},
|
|
})
|
|
|
|
|
|
if (!user) {
|
|
return NextResponse.json(
|
|
{ success: false, error: '用户不存在' },
|
|
{ status: 401 }
|
|
)
|
|
}
|
|
|
|
// 验证密码
|
|
const passwordMatch = await compare(password, user.password || '')
|
|
|
|
if (!passwordMatch) {
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: '密码错误'
|
|
}, { status: 401 })
|
|
}
|
|
|
|
// 创建会话
|
|
const sessionToken = crypto.randomUUID()
|
|
await prisma.session.create({
|
|
data: {
|
|
id: sessionToken,
|
|
userId: user.id,
|
|
expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
|
|
}
|
|
})
|
|
|
|
// 设置cookie
|
|
const response = NextResponse.json({
|
|
success: true,
|
|
user: {
|
|
id: user.id,
|
|
phone: user.phone,
|
|
name: user.name
|
|
}
|
|
})
|
|
|
|
response.cookies.set('session', sessionToken, {
|
|
httpOnly: true,
|
|
// secure: process.env.NODE_ENV === 'production',
|
|
maxAge: 60 * 60 * 24 * 7
|
|
})
|
|
|
|
return response
|
|
|
|
} catch (error) {
|
|
console.error('登录错误:', error)
|
|
return NextResponse.json(
|
|
{ success: false, error: '服务器错误,请稍后重试' },
|
|
{ status: 500 }
|
|
)
|
|
}
|
|
} |