首页 > 数据库 >【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (六):token的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (六):token的设置

时间:2024-10-24 10:02:05浏览次数:1  
标签:RestfulAPI NodeJS mongoDB 用户 token user res email

本项目旨在学习如何快速使用 nodejs 开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师)
由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序(并非循序渐进的教学文档)。建议配合项目源码node-mongodb-template

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (一):项目简介及安装依赖

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (二):项目文件夹架构及路由的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (三):Cors的设置及.env文件的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (四):状态码的使用

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (五):POST上传文件的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (六):token的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (七):MongoDB的设置

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (八):API说明(暂时完结,后续考虑将在线版mongoDB变为本地版)

token的设置

通过API查看数据时,不同的数据可能存在权限的要求,比如通常所有用户包括游客都可以查看products,但是只有登录的用户可以增加/删除/修改产品,只有登录的用户可以增删改查订单。

那么就需要设置用户登录的功能,用户登录成功之后,会在返回信息中提供token,程序就会校验token是否满足权限,然后在进行api请求。

实现

安装依赖

实现过程中需要两个依赖

pnpm i --save bcrypt 加密,用于用户密码的加密和校验

pnpm i --save jsonwebtoken token, 用户生成和校验token

用户登录

用户登录的功能,需要用户类,可以注册用户,删除用户和登录。用户的密码需要进行加密,进行登录请求的时候需要生成token。

用户表设计
//models/user.js
const mongoose = require('mongoose');

const userSchema = mongoose.Schema({
    _id:mongoose.Schema.Types.ObjectId,
    email:{
        type:String, 
        required:true,
        unique:true,
        match:/(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/
    },
    password:{type:String, required:true},
})

module.exports = mongoose.model('User', userSchema);
用户API设计
const express = require('express');
const router= express.Router();

const checkAuth = require('../middleware/check-auth');

const userController = require('../controllers/user')

router.post('/signup',userController.user_signup);

router.post('/login',userController.user_login);

router.delete('/:userId',checkAuth,userController.user_delete);

module.exports = router;

用户注册:加密

exports.user_signup = (req,res,next) => {
    User.findOne({email: req.body.email})
    .exec()
    .then(user=>{
        if(user){
            res.status(409).json({
                message:"Mail exists"
            });
        }else{
          //密码加密
            bcrypt.hash(req.body.password,10,(err,hash) => {
                if(err){
                    return res.status(500).json({
                        err:err
                    })
                }else{
                    const user = new User({
                        _id:new mongoose.Types.ObjectId(),
                        email:req.body.email,
                        password:hash
                    });
                    user
                    .save()
                    .then(result=>{                       
                        res.status(201).json({
                            message:'Create user successfully' ,
                            createdUser: {
                                result: result,
                            }
                        });
                    })
                    .catch(err=>{
                        res.status(500).json({
                            error:err
                        });
                    });
                }
            })
        }
    })
    .catch(err=>{
        res.status(500).json({
            error:err
        });
    });
};

用户登录: 校验密码、生成token

exports.user_login = (req,res,next) => {
    User.find({email: req.body.email})
    .exec()
    .then(user=>{
        if(user.length<1){
            res.status(401).json({
                message:"Auth Failed"
            });
        }else{
          //检查密码是否正确
            bcrypt.compare(req.body.password,user[0].password,(err,result) => {
                if(err){
                    res.status(401).json({
                        message:"Auth Failed"
                    });
                }
                if(result){
                  //生产token
                    const token = jwt.sign({
                        email:user[0].email,
                        userId:user[0]._id
                    },process.env.JWT_KEY,{
                        expiresIn:"1h",
                    });
                    res.status(200).json({
                        message:"Auth successfully",
                        token:token,
                        request:{
                            type: 'POST',
                            url: 'http://localhost:3000/user/signup',
                            body:{
                                email:"string",
                                password:"string"
                            }
                        }
                    });
                }else{
                    res.status(401).json({
                        message:"Auth Failed"
                    });
                }
            })
        }
    })
    .catch(err=>{
        res.status(500).json({
            error:err
        });
    });
};

用户删除: 校验token

exports.user_delete = (req,res,next) => {
    const id = req.params.userId;
    User.deleteOne({_id:id})
    .exec()
    .then(result=>{
        res.status(200).json({
            message:"User deleted successfully",
            request:{
                type: 'POST',
                url: 'http://localhost:3000/user/signup',
                body:{
                    email:"string",
                    password:"string"
                }
            }
        });      
    })
    .catch(err=>{
        res.status(500).json({
            error:err
        });
    });
};

校验token

由于多处需要校验用户是否登录,即校验token。因此应该将校验token的部分单独作为一个中间件,在api请求时,进行使用。

中间件

新建文件夹middleware,然后新建文件check-auth.js

const jwt = require('jsonwebtoken');

module.exports = (req,res,next)=>{
    try{
        const token = req.headers.authorization.split(" ")[1];
        const decoded = jwt.verify(token,process.env.JWT_KEY);
        req.userData = decoded;
        next();
    }
    catch(error){
        return res.status(401).json({
            message:'Auth failed'
        });
    }
};
api请求前校验token

这里以前文中用户删除为例,用户的删除操作只能是用户登录的状态下进行,因此需要进行校验。

可以看到如下代码

const checkAuth = require('../middleware/check-auth');
//校验的中间件写在请求中。
router.delete('/:userId',checkAuth,userController.user_delete);

如果遇到既需要校验,有需要上传文件的操作是,校验要写在上传文件中间件之前,如增加一个产品。

router.post('/',checkAuth,upload.single('productImage'),productsController.create_product);

postman中输入token进行请求

注册用户

POST localhost:3000/user/signup

Body如下

{
    "email":"[email protected]",
    "password":"0000000"
}
登录用户

POST localhost:3000/user/login

Body如下

{
    "email":"[email protected]",
    "password":"0000000"
}

请求成功之后,返回如下

{
    "message": "Auth successfully",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6IjEyM0B0ZXN0LmNvbSIsInVzZXJJZCI6IjY2ZTA1NGY5YTM1ZmM4OGQ0YTRhNjY5ZSIsImlhdCI6MTcyNjIzODI2OCwiZXhwIjoxNzI2MjQxODY4fQ.W8_9mmBLU4IzcycEh6sNO95wlepp6qQJToOdM9LgEQ4",
    "request": {
        "type": "POST",
        "url": "http://localhost:3000/user/signup",
        "body": {
            "email": "string",
            "password": "string"
        }
    }
}

其中包括 token 的值,复制

查询订单

GET localhost:3000/orders

Header中新增一个属性 Authorization, 并将值输入为如下 Bearer [token]

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6IjEyM0B0ZXN0LmNvbSIsInVzZXJJZCI6IjY2ZTA1NGY5YTM1ZmM4OGQ0YTRhNjY5ZSIsImlhdCI6MTcyNjIzODI2OCwiZXhwIjoxNzI2MjQxODY4fQ.W8_9mmBLU4IzcycEh6sNO95wlepp6qQJToOdM9LgEQ4

然后点击发送请求,此时就可以请求成功了。

标签:RestfulAPI,NodeJS,mongoDB,用户,token,user,res,email
From: https://www.cnblogs.com/sitarblogs/p/18498940

相关文章

  • 【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (七):MongoDB的设置
    本项目旨在学习如何快速使用nodejs开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师)由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序(并非循序渐进的教学文档)。建议配合项目源码node-mongodb-template。【NodeJS......
  • 【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (三):Cors的设置及.env文件的设置
    本项目旨在学习如何快速使用nodejs开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师)由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序(并非循序渐进的教学文档)。建议配合项目源码node-mongodb-template。【NodeJS......
  • 【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (二):项目文件夹架构及路由的设置
    本项目旨在学习如何快速使用nodejs开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师)由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序(并非循序渐进的教学文档)。建议配合项目源码node-mongodb-template。【NodeJS......
  • 【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (八):API说明(暂时完结,后续考虑将
    本项目旨在学习如何快速使用nodejs开发后端api,并为以后开展其他项目的开启提供简易的后端模版。(非后端工程师)由于文档是代码写完之后,为了记录项目中需要注意的技术点,因此文档的叙述方式并非开发顺序(并非循序渐进的教学文档)。建议配合项目源码node-mongodb-template。【NodeJS......
  • flask+python+html+mongodb
     python运行此文件,跳转到index.htmlfromflaskimportFlask,render_template,request,jsonify,json,url_for,redirectapp=Flask(__name__)@app.route('/',methods=['GET','POST'])defindex():returnrender_template('index.......
  • nodejs基于Vue的二手交易系统(源码+vue+部署文档+前后端分离等)
    收藏关注不迷路!!......
  • mongoDB学习之--docker安装mongoDB
    一、环境准备:操作系统:centos9stream:5.14.0-522.el9.x86_64docker版本:27.3.1由于最近镜像加速器也被禁的很厉害,很多要么申请白名单,要么得像阿里一样申请二级域名;可惜配置了申请的阿里域名依然还是连不上dockerhub, {"registry-mirrors":["https://xxxxxx.mirror.a......
  • MongoDB 可以处理的连接数
    影响连接限制的因素1.硬件资源:服务器(CPU、内存)越强大,理论上可处理的连接数就越多。2.MongoDB版本:不同版本的MongoDB可能有不同的默认值或最大连接数。3.操作系统配置:操作系统对文件描述符的限制会直接影响MongoDB可处理的最大连接数。每个连接都会使用一个文件描述符,而......
  • MongoDB数据备份&导入导出&同步
    mongodump&mongorestore单库备份##-o输出目录mongodump--host127.0.0.1--port27032-uxxx-pxxx--dbtest2--oplog-o./test2全库备份--oplog只能在副本集中使用,因为副本集初始化的时候生成oplog,单实例使用--oplog会报错。mongodump--host127.0.0.1--port......
  • MongoDB 5 安装&副本集搭建&集群搭建
    单节点安装需要一个数据目录地址,一个日志文件地址,配置文件##数据目录地址--dapath=##日志文件--logpath=##配置文件--config=***.conf下载https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-5.0.27.tgz启动命令/data/dba/yanhao/application/mongodb/bin/mong......