从零开始用react + tailwindcs + express + mongodb实现一个聊天程序(三) 实现注册 登录接口

1.划分文件夹

在src目录下创建controllers middleware models routes

controllers 放具体的方法 signup login

middleware 里面是中间件 请求的验证

models 放对象实体

routes 处理访问路径像/signup /login 等等

2. 接口开发

系统的主要 有用户认证 和 消息 2种类型服务

在index下面添加如下代码

javascript 复制代码
import authRoutes from './routes/auth.route.js'
import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser'

// 解决req.body undefined问题
app.use(cookieParser())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
// 实现signup 注册接口 认证
app.use('/api/auth', authRoutes)

/api/auth 是路由前缀 authRoutes是 处理请求的路由

在刚刚建好的routes文件夹下 创建auth.route.js 内容如下

javascript 复制代码
import express from 'express';

import {signUp, login} from "../controllers/auth.controller.js"


const router = express.Router();

router.post('/signup', signUp)
router.post('/login', login)

export default router;

在models下创建user.model.js 创建user对象schema 作用是和数据库关联 (用法详见mongodb教程)

javascript 复制代码
import mongoose from "mongoose";
const userSchema = new mongoose.Schema({
    email: {
        type: String,
        required: true,
        unique: true
    },
    password: {
        type: String,
        required: true,
        minlenght: 6
    },
    userName: {
        type: String,
        required: true
    },
    profilePic: {
        type: String,
        default: ''
    }
}, {timestamps: true});

const User = mongoose.model('User', userSchema);

export default User;

在lib文件夹下创建 util.js

javascript 复制代码
import jwt from 'jsonwebtoken'

export const generateToken = (userId,res) => {
    
    // 7天有效期
    const token = jwt.sign({userId},process.env.JWT_SECRET,{expiresIn:'7d'})

    res.cookie('jwt',token,{
        maxAge: 1000 * 60 * 60 * 24 * 7,
        httpOnly: true,
        sameSite: "strict",
        secure: process.env.NODE_ENV !== 'development'
    })

    return token
}

在 /server/.env下 加 JWT_SECRET=mysecret 配置

在controllers文件夹下创建auth.controller.js 写我们的接口逻辑

javascript 复制代码
import { generateToken } from "../lib/util.js";
import User from "../models/user.model.js";
import bcrypt from "bcryptjs";

// 实现signup接口
export const signUp = async (req, res) => {
    const { userName,password, email } = req.body
    // TODO: implement signup
    // 判断字段是否全部输入
    try {
        if (!userName || !password || !email) {
            return res.status(400).json({ message: '缺失字段' })
        }
        // 判断密码长度
        if (password.length < 6) {
            return res.status(400).json({ message: '密码长度不能小于6位' })
        }
        // 判断用户名是否已存在
        const user = await User.findOne({ email })

        if(user) {
            return res.status(400).json({ message: '邮箱已存在' })
        }
        // 密码加密
        const salt = await bcrypt.genSalt(10)
        const hashPassword = await bcrypt.hash(password,salt)

        // 创建用户
        const newUser = new User({
            userName,
            email,
            password: hashPassword
        })
        // 保存用户
        if(newUser) {
            generateToken(newUser._id,res)
            await newUser.save()

            res.status(201).json({
                _id: newUser._id,
                userName: newUser.userName,
                email: newUser.email,
                profilePic: newUser.profilePic,
            })
        }
    } catch (err) {
        return res.status(500).json({ message: '内部服务器错误' })
    }
}

// 登录
export const login = async (req, res) => {
    const {password, email} = req.body
    try {
        const user = await User.findOne({ email })
        if (!user) {
            return res.status(400).json({ message: '认证失败' })
        }

        // 比较密码
        const isMatch = await bcrypt.compare(password, user.password)
        if (!isMatch) {
            return res.status(400).json({ message: '认证失败' })
        }

        generateToken(user._id,res)
        res.status(200).json({
            _id: user._id,
            userName: user.userName,
            email: user.email,
            profilePic: user.profilePic
        })
    } catch (err) {
        return res.status(500).json({ message: '内部服务器错误' })
    }
}

// 退出
export const logout = async (req, res) => {
    try {
        res.cookie("jwt","", {maxAge:0})
        res.status(200).json({ message: '退出成功' })
    } catch (err) {
        return res.status(500).json({ message: '内部服务器错误' })
    }
}

3. postman测试接口

1.signup 注册接口

密码输入1 小于6位

注册成功返回用户信息

查看数据库 有我们刚才注册的信息 并且密码也已加密

2.login 登录接口

返回用户信息 登录成功

3. logout 登出

提示退出成功

以上就是本篇内容 下篇我们实现前端 页面 实现注册 登录页面 并和后端接口联调。如有问题评论私信都可以联系我 一起交流

相关推荐
kyriewen22 分钟前
白宫直接给 OpenAI 下了限制令,GPT-5.6 不能随便放出来了
前端·javascript·面试
PedroQue991 小时前
Vite插件v0.2.6:架构优化与自动化升级
前端·vite
threerocks3 小时前
什么?我连 A2A、MCP 都没学会,现在又来了 AG-UI、A2UI.
前端·aigc·ai编程
牛奶3 小时前
如何自己写一个浏览器插件?
前端·chrome·浏览器
hoLzwEge4 小时前
pnpm-lock.yaml
前端框架
亿元程序员4 小时前
为什么Cocos都4.0了还有人用2.x?
前端
MomentYY4 小时前
AI 到底是“懂”,还是在“猜”?
前端·人工智能·ai编程
鹏毓网络科技4 小时前
Cursor Rules 文件配置实战:3 个隐藏参数让我每月少写 40% 样板代码
前端·github
没烦恼3014 小时前
无痕模式下 HTTP\-First 拦截引发的“页面刷新”误判
前端
ZhengEnCi4 小时前
Q02-Vue-React-index.html完全指南
vue.js·react.js·html