env
配置
我们可以在next.config.mjs
中的nextConfig
对象下面,直接设置env
对象,这样就可以在tsx
中通过process.env.xxx
获取
修改next.config.mjs
js
/** @type {import('next').NextConfig} */
const nextConfig = {
env: {
BASE_URL: 'http://localhost:3000',
MONGODB_URL: 'mongodb://root:123456@127.0.0.1:27017/next-shopping',
ACCESS_TOKEN_SECRET: '1233211234567890',
REFRESH_TOKEN_SECRET: '987654321',
},
}
export default nextConfig
数据库函数
本项目采用的是mongodb
数据库,所以可以使用monoose
依赖:
shell
pnpm i mongoose
新建lib/db.js
js
import mongoose from 'mongoose'
const connection = {}
async function connect() {
if (connection.isConnected) {
console.log('already connected')
return
}
if (mongoose.connections.length > 0) {
connection.isConnected = mongoose.connections[0].readyState
if (connection.isConnected === 1) {
console.log('use previous connection')
return
}
await mongoose.disconnect()
}
try {
console.log('process.env.MONGODB_URL', process.env.MONGODB_URL)
const db = await mongoose.connect(process.env.MONGODB_URL)
console.log('new connection')
connection.isConnected = db.connections[0].readyState
} catch (error) {
console.log(error)
process.exit(1)
}
}
async function disconnect() {
if (connection.isConnected) {
if (process.env.NODE_ENV === 'production') {
await mongoose.disconnect()
connection.isConnected = false
} else {
console.log('not disconnected')
}
}
}
const db = { connect, disconnect }
export default db
用户模块
创建models/user.js
js
import mongoose from 'mongoose'
const userSchema = new mongoose.Schema({
name: { type: String, require: true },
email: { type: String, require: true, unique: true },
password: { type: String, require: true },
role: { type: String, default: 'user' },
root: { type: Boolean, default: false },
avatar: {
type: String,
default:
'https://images.pexels.com/photos/17022636/pexels-photo-17022636.jpeg?auto=compress&cs=tinysrgb&w=800&lazy=load',
},
})
const User = mongoose.models.user || mongoose.model('user', userSchema)
export default User
实现token函数
下载jsonwebtoken
依赖:
shell
pnpm i jsonwebtoken
新建utils/generateToken.js
js
import jwt from 'jsonwebtoken'
export const createAccessToken = payload => {
return jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: '15min',
})
}
export const createRefreshToken = payload => {
return jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET, {
expiresIn: '7d',
})
}
新建utils/sendError.js
js
import { NextResponse } from 'next/server'
export default function sendError(status, msg) {
return NextResponse.json({ err: msg }, { status: status })
}
实现login
和register
API
安装bcrypt
依赖:
shell
pnpm i bcrypt
新建app/auth/login/route.js
js
import { NextResponse } from 'next/server'
import bcrypt from 'bcrypt'
import db from '@/lib/db'
import Users from '@/models/User'
import sendError from '@/utils/sendError'
import { createAccessToken, createRefreshToken } from '@/utils/generateToken'
export async function POST(req) {
try {
await db.connect()
const { email, password } = await req.json()
const user = await Users.findOne({ email })
if (!user) return sendError(400, '找不到此电子邮件的应用程序')
const isMatch = await bcrypt.compare(password, user.password)
if (!isMatch) return sendError(400, '电子邮件地址或密码不正确')
const access_token = createAccessToken({ id: user._id })
const refresh_token = createRefreshToken({ id: user._id })
return NextResponse.json(
{
msg: '登录成功',
refresh_token,
access_token,
user: {
name: user.name,
email: user.email,
role: user.role,
avatar: user.avatar,
root: user.root,
},
},
{ status: 200 }
)
} catch (error) {
console.log('====error====', error.message)
return sendError(500, error.message)
}
}
新建app/auth/register/route.js
js
import { NextResponse } from 'next/server'
import bcrypt from 'bcrypt'
import db from '@/lib/db'
import Users from '@/models/User'
import sendError from '@/utils/sendError'
export async function POST(req, { params }) {
try {
await await db.connect()
const { name, email, password } = await req.json()
const user = await Users.findOne({ email })
if (user) return sendError(400, '该账户已存在')
const hashPassword = await bcrypt.hash(password, 12)
const newUser = new Users({ name, email, password: hashPassword })
await newUser.save()
await db.disconnect()
return NextResponse.json(
{
meg: '注册成功',
},
{
status: 201,
}
)
} catch (error) {
return sendError(500, error.message)
}
}
结果如下: