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

提示退出成功

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

相关推荐
拳打南山敬老院7 小时前
Context 不是压缩出来的,而是设计出来的
前端·后端·aigc
用户3076752811278 小时前
💡 从"傻等"到"流淌":我在AI项目中实现流式输出的血泪史(附真实代码+深度解析)
前端
bluceli8 小时前
前端性能优化实战指南:让你的网页飞起来
前端·性能优化
UIUV8 小时前
RAG技术学习笔记(含实操解析)
javascript·langchain·llm
SuperEugene8 小时前
Vue状态管理扫盲篇:如何设计一个合理的全局状态树 | 用户、权限、字典、布局配置
前端·vue.js·面试
没想好d8 小时前
通用管理后台组件库-9-高级表格组件
前端
阿虎儿8 小时前
React Hook 入门指南
前端·react.js
核以解忧8 小时前
借助VTable Skill实现10W+数据渲染
前端
WangHappy8 小时前
不写 Canvas 也能搞定!小程序图片导出的 WebView 通信方案
前端·微信小程序
李剑一8 小时前
要闹哪样?又出现了一款新的格式化插件,尤雨溪力荐,速度提升了惊人的45倍!
前端·vue.js