从零开始用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 登出

提示退出成功

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

相关推荐
Larcher6 小时前
React Router 不只是页面跳转:从 SPA 路由到权限守卫的完整实践
javascript·后端
Larcher6 小时前
大模型为什么每次回答都不一样?一文搞懂 Temperature、Top K 与 Top P
javascript·后端
用户938515635079 小时前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战
前端·设计模式·typescript
CodeSheep9 小时前
稚晖君公司人事大变动,来了!
前端·后端·程序员
鱼樱前端9 小时前
用 AI 做内容变收入
前端·人工智能·ai编程
eric-sjq9 小时前
10 分钟实战:用 0.6B 本地模型生成中文网页(WanlyFrontend + 编译器全流程)
javascript·机器学习·自然语言处理·html
浮生望10 小时前
React + TypeScript 组件设计进阶:从类型约束到无状态组件的三次进化
前端
To_OC10 小时前
LC 438 找到所有字母异位词:暴力超时后,我靠滑动窗口一招搞定
javascript·算法·leetcode
90后的晨仔10 小时前
Mac 开发 uni-app 终极方案:让安卓模拟器彻底脱离 Android Studio 独立运行
前端·vue.js
90后的晨仔10 小时前
别再搞混了!uni-app 中 node_modules 和 uni_modules 到底是什么关系?
前端