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

提示退出成功

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

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄3 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端