「2」next-shopping:数据库+登录注册

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 })
}

实现loginregister 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)
  }
}

结果如下:

相关推荐
Jiaberrr2 分钟前
开启鸿蒙开发之旅:交互——点击事件
前端·华为·交互·harmonyos·鸿蒙
Json____17 分钟前
学法减分交管12123模拟练习小程序源码前端和后端和搭建教程
前端·后端·学习·小程序·uni-app·学法减分·驾考题库
迂 幵26 分钟前
vue el-table 超出隐藏移入弹窗显示
javascript·vue.js·elementui
上趣工作室30 分钟前
vue2在el-dialog打开的时候使该el-dialog中的某个输入框获得焦点方法总结
前端·javascript·vue.js
家里有只小肥猫30 分钟前
el-tree 父节点隐藏
前端·javascript·vue.js
fkalis31 分钟前
【海外SRC漏洞挖掘】谷歌语法发现XSS+Waf Bypass
前端·xss
zxg_神说要有光1 小时前
自由职业第二年,我忘记了为什么出发
前端·javascript·程序员
陈随易2 小时前
农村程序员-关于小孩教育的思考
前端·后端·程序员
云深时现月2 小时前
jenkins使用cli发行uni-app到h5
前端·uni-app·jenkins
昨天今天明天好多天2 小时前
【Node.js]
前端·node.js