项目:在线课堂

1.1 项目技术栈说明:

前端技术: HTML5、CSS3、ajax、jquery、token(jwt)

后端技术:NODE.js express MySQL、jwt(token)

1.2 功能模块:

实现了首页课程渲染、列表页筛选课程,搜索课程,课程详情介绍,视频播放,报名课程,登录,注册,个人中心等。具体实现如下:

使用 Node,Express,MySQL 完成底层接口的编写

登入模块整合 JWT,为每个学生用户生成一个单独的 token

使用存储在本地缓存中的 token 进行用户的身份验证,保证用户可以报名课程和个人信 息的管理

使用 Jquery 的 Ajax 方法进行请求接口,进行渲染页面

1.3初始化项目

(1)使用express脚手架,生成项目基本结构

(2)把nodemon工具配置到 package.json

(3)删除app.js中不需要的一些代码

(4)修改app.js中的404配置和错误配置

(5)使用navicat工具导入数据库

(6)安装必备模块包:cors、formidable、mysql 等

(7)运行项目进行开发

(8) 使用git和码云进行托管项目

1.4数据模型分析

e_banners 轮播图

e_area 地区表

e_category 课程分类,如期中、期末

e_grade 年级

e_subject 课程

e_type 课程版本分类

e_course 课程详细信息

e_member 会员表

e_order 订单表,会员购买某课程的信息

e_teacher 教师信息表

e_video 课程视频表

1. 首页课程列表

功能描述:根据请求类别参数的不同获取同步课程或精品课程数据

设计思路:

(1)接口地址 “/courselist” get请求

(2)传递参数为type:区分课程类别

代码案例:

 

2. 分类相关接口

自主实现

2.1 地区

功能描述:获取地区数据

设计思路:

(1)接口地址 “/areas” get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

 

2.2 年级

功能描述:获取年级数据

设计思路:

(1)接口地址 “/grades”get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

2.3 学科

功能描述:获取学科数据

设计思路:

(1)接口地址 “/subjects” get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

2.4 考试类别

功能描述:获取考试类型数据

设计思路:

(1)接口地址 “/cates” get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

3. 列表页

功能描述:获取课程列表。当从首页点击“更多课程”时跳转到该页面。默认给用户显示所有课程信息,有分页功能

设计思路:

(1)接口地址 “/courses” post请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

 

4. 搜索

自主实现

功能描述:根据查询关键字获取课程列表

设计思路:

(1)接口地址 “/searchlist”get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

 

5. 课程详情

自主实现

功能描述:根据课程id获取课程详情信息。需要根据cid, 去 e_course、e_teacher、e_video表中查询课程信息、教师信息、课程视频信息

设计思路:

(1)接口地址 “/apiv1/course/coursedetail?cid=1beec178-4b02-40fb-9d1c-8aa61cd4a098” get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

6. 课程视频

功能描述:根据视频id获取课程的视频地址

设计思路:

(1)接口地址 “/videoplay/:id” get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

代码案例:

 

7. 报名课程

自主实现

功能描述:根据当前登录用户和课程id进行报名

设计思路:

(1)接口地址 “/study” post请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

 

8. 个人中心

8.1 注册

功能描述:根据用户名和密码实现注册

设计思路:(1)接口地址 “/register”post请求 (2)查看数据表信息及数据库字典 (3)设置sql语句

 

8.2 登录

功能描述:根据用户名和密码实现登录功能,返回登录标识token

设计思路:(1)接口地址 “/login”post请求 (2)查看数据表信息及数据库字典 (3)设置sql语句

8.3 token

8.4 获取用户

自主实现

功能描述:根据用户id,获取对应的用户信息

设计思路:

(1)接口地址 “/user/:id” get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

难点:需要验证token

8.5 更新用户

自主实现

功能描述:根据用户id,更新对应的用户信息

设计思路:

(1)接口地址 “/user/:id”post请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

难点:参数较多,需要验证token

8.6 更新用户头像

自主实现

功能描述:根据用户id和传递过来的头像,更新用户头像

设计思路:

(1)接口地址 “/uploadhead”post请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

难点:需要验证token,文件上传

Ajax简单异步上传图片并回显:

<img src="../img/login/user.png" class="myIcon" id="myIcon"/>
<div class="change">
  更换头像
  <input type="file" class ="btn_file" id="btn_file" />
</div>
​
$("#btn_file").on("change",function(){
    let mid = "4e71f670-bf81-11eb-b856-9385244f466c";
    let formData = new FormData();
    formData.append("photo",this.files[0])
    formData.append("mid",mid);
    $.ajax({
        type: "put",
        url: "/v1/member/uploadhead",
        data: formData,
        contentType: false,
        processData: false,
        dataType: "json",
        success: function (response) {
            console.log( response);
            $("#myIcon").attr("src","/"+response.data.originName);
        }
    });
})

 

8.7 用户的学习记录

自主实现

功能描述:获取当前登录用户的学习记录

设计思路:

(1)接口地址 “/orders” get请求

(2)查看数据表信息及数据库字典

(3)设置sql语句

难点:需要验证token,连表查询

项目结构

4509284eabd34d8c9e47a38ccd1146d1.png

15bbabae2ade4a1cb4de940231090785.png

7bb4e019e9634b04b68a196dad805ed6.png

 路由及配置代码如下:

routes        

course.js

var express = require('express');
let db = require('../tools/db');
let intercept = require('../tools/intercept');
let time = require('time-stamp');

var router = express.Router();
/* 
//生成jwt字符串
let payload = {
    username: '张三',
    exp: Date.now() + (1000 * 60 * 60 * 24),
}
let token = jsonwebtoken.sign(payload, secret);
console.log(token);
//检验token是否被篡改
jsonwebtoken.verify(token, secret, (err, decoded) => {
    if (!err) {
        //检验成功
        console.log(decoded);
        //判断当前时间大于exp则过期
    } else {
        //检验失败
        console.log('失败');
    }
})
 */

//根据cid获取课程详情,以及该课程视频信息
router.get('/detail', async (req, res) => {
    let cid = req.query.cid;
    let sql1 = `SELECT
	a.id,
	a.tid,
	a.title,
	price,
	concat( '/uploads/course/', a.image_src ) AS image_src,
	a.type_name,
	a.area_name,
	a.grade_name,
	a.subject_name,
	a.category_name,
	a.intro AS courseIntro,
	b.intro AS teacherIntro,
	b.realname,
	concat( '/uploads/avatar/', b.head_photo_url ) AS head_photo_url 
FROM
	e_course AS a
	LEFT JOIN e_teacher AS b ON a.tid = b.tid 
WHERE
	a.cid = ?`;

    let sql2 = `select id,cid,vnum,video_src,video_title from e_video where cid = ?`;

    // let a = await db.query(sql1,[cid]);
    // let b = await db.query(sql2,[cid]);

    Promise.all([
        db.query(sql1, [cid]),
        db.query(sql2, [cid])
    ]).then((data) => {
        console.log(data);
        //将数据包装成前端想要的数据
        let obj = data[0][0];
        obj.vodeo = data[1];
        res.json({
            code: 200,
            data: obj,
            msg: '课程详情响应成功'
        })
    }).catch((err) => {
        res.json({
            code: 500,
            data: err,
            msg: '课程数据失败'
        })
    })

})



//token拦截验证中间件,需要验证的接口放在下面
router.use(intercept());

//视频播放接口
router.get('/videoplay', async (req, res) => {
    let {
        id
    } = req.query;
    let sql = `select cid,vnum,concat('/uploads/video/',video_src) as video_src,video_title  from e_video where id=?`;
    let a = await db.query(sql, [id]);
    res.json({
        code: 200,
        data: a[0],
        msg: '响应成功'
    })
})


//课程报名
router.post('/study', async (req, res) => {
    let {
        cid,
        mid
    } = req.body;
    //健壮性考虑
    if (!cid || !mid) {
        res.json({
            code: 201,
            data: null,
            msg: 'cid和mid不能为空'
        });
    }
    //作业:检查该课程是否已报过名(如果mid代表的这个人已经报过该课程就提示不能重复报名)
    let sql2 = `select * from e_order where mid=? and cid=?`;
    let data = await db.query(sql2, [mid, cid]);
    if (data.length > 0) {
        //提示不能重复报名
        res.json({
            code: 201,
            data: null,
            msg: '不能重复报名'
        })
    } else {
        //不存在
        let sql = `insert into e_order(oid,cid,mid,createdate) values(?,?,?,?)`;

        let oid = time("YYYYMMDDHHmmssms");
        let a = await db.query(sql, [oid, cid, mid, Date.now()]);

        res.json({
            code: 200,
            data: null,
            msg: '课程报名成功'
        })
    }


})

module.exports = router;

index.js

var express = require('express');
let db = require('../tools/db');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
  res.json({
    code: 200,
    data: null,
    msg: '欢迎访问小优课堂v1.0'
  })
});

//轮播图接口
router.get('/banner', async function (req, res) {
  let a = await db.query(`select id,concat('/uploads/',image_src) as image_src,title,isshow from e_banners where isshow=1`);
  res.json({
    code: 200,
    data: a,
    msg: '成功响应轮播图数据'
  })
});

//首页课程列表接口
router.get('/courselist', async (req, res) => {
  let {
    type = 1,
      num = 8,
  } = req.query;

  let sql = `select id,cid,title,price,concat('/uploads/course/',image_src) as image_src,type_name,area_name,grade_name,subject_name,category_name from e_course where type=${type} LIMIT 0,?`;

  let a = await db.query(sql, [parseInt(num)]);
  res.json({
    code: 200,
    data: a,
    msg: '成功响应首页课程列表数据'
  })
})

//搜索接口
router.post('/searchlist', async (req, res) => {
  let {
    keyword,
    page,
    pagesize
  } = req.body;

  let start = (parseInt(page) - 1) * parseInt(pagesize);

  let sql = `select id,cid,title,price,concat('/uploads/course/',image_src) as image_src,type_name,area_name,grade_name,subject_name,category_name from e_course where title like '%${keyword}%' LIMIT ${start},${pagesize}`;
  let sql2 = `select * from e_course where title like '%${keyword}%'`;
  let b = await db.query(sql2);
  let a = await db.query(sql);
  res.json({
    code: 200,
    b,
    data: {
      page: parseInt(page),
      pagesize: parseInt(pagesize),
      result: a
    },
    msg: '成功响搜索数据'
  })
})

module.exports = router;

list.js

var express = require('express');
let db = require('../tools/db');
let to = require('../tools/to');
var router = express.Router();

//列表页
//1.数据筛选
router.post('/courses', async (req, res) => {
    let {
        type = 1,
            area = "",
            grade = "",
            subject = "",
            category = "",
            price = "desc",
            page = 1,
            pagesize = 9
    } = req.body;

    // if(!type || !page || !pagesize){}
    let start = (page - 1) * pagesize; //起始记录位置换算公式
    let str = '';
    if (area) {
        str += ` and area_name='${area}' ` //前后必须留一个空格
    }
    if (grade) {
        str += ` and grade_name='${grade}' `
    }
    if (subject) {
        str += ` and subject_name='${subject}' `
    }
    if (category) {
        str += ` and category_name='${category}' `
    }

    let sql = `select id,cid,title,price,concat('/uploads/course/',image_src) as image_src,type_name,area_name,grade_name,subject_name,category_name  from e_course where type=${type} ${str}  ORDER BY price ${price} LIMIT ${start},${pagesize}`;

    //查询符合条件的总记录数
    let sql2 = `select count(id) as totalnum  from e_course where type=${type} ${str}`;
    let [{
        totalnum
    }] = await db.query(sql2);
    // console.log(totalnum);

    // console.log(str);
    // console.log(sql);
    /* let a = await db.query(sql);
    res.json({
        code: 200,
        data: a,
        msg: '成功响应筛选数据'
    }) */

    let [err, result] = await to(db.query(sql));
    if (!err) {
        res.json({
            code: 200,
            data: {
                totalnum,
                page: parseInt(page),
                pagesize: parseInt(pagesize),
                result,
            },
            msg: '成功响应筛选数据'
        })
    } else {
        res.json({
            code: 200,
            data: err,
            msg: '响应失败'
        })
    }
})

//2.地区接口 /areas
router.get('/areas', async (req, res) => {
    let a = await db.query('select * from e_area');
    res.json({
        code: 200,
        data: a,
        msg: '响应地区数据成功'
    })
})

//3.年级接口 /grades
router.get('/grades', async (req, res) => {
    let a = await db.query('select * from e_grade');
    res.json({
        code: 200,
        data: a,
        msg: '响应年级数据成功'
    })
})
//4.学科接口 /subjects
router.get('/subjects', async (req, res) => {
    let a = await db.query('select * from e_subject');
    res.json({
        code: 200,
        data: a,
        msg: '响应年级数据成功'
    })
})
//5.考试类别接口 /categorys
router.get('/categorys', async (req, res) => {
    let a = await db.query('select * from e_category');
    res.json({
        code: 200,
        data: a,
        msg: '响应年级数据成功'
    })
})



module.exports = router;

users.js

var express = require('express');
let mysql = require('../tools/db');
let {
  secret
} = require('../tools/config');
let to = require('../tools/to');
let jwt = require('jsonwebtoken');
let md5 = require('md5');
let uuid = require('uuid');
let intercept = require('../tools/intercept');
let formidable = require('formidable');
let path = require('path');
let fs = require('fs');
var router = express.Router();


/新闻
router.post('/news', async (req, res) => {
  let {
    title,
    pubdate,
    author,
    content,
    newsPic,
    addtime
  } = req.body;

  let sql = `INSERT INTO news(title, pubdate, author, content,newsPic, addtime) VALUES(?,?,?,?,?,?)`;
  let a = await mysql.query(sql, [title, pubdate, author, content, newsPic, addtime]);

  if (a.affectedRows > 0) {
    //更新成功后信息也需要返回给前端
    res.json({
      code: 200,
      data: null,
      msg: '新闻添加成功'
    });
  } else {
    res.json({
      code: 201,
      data: null,
      msg: '新闻添加失败'
    });
  }
})

router.post('/uploadhead', (req, res) => {
  //初始化 设置上传文件的存放目录
  let form = formidable({
    uploadDir: './uploads/news',
    // maxFields: 1024 * 200  设置上传文件大小
  });
  form.parse(req, async (err, fields, files) => {
    // console.log(fields, files);
    //如果出错结束代码
    if (err) {
      res,
      json({
        code: 500,
        data: err,
        msg: '上传失败请重试'
      })
      return;
    }
    console.log(files);
    let {
      userphoto: {
        filepath,
        newFilename,
        originalFilename
      }
    } = files;

    // 1) 从原始文件中提取扩展名
    let extName = path.extname(originalFilename); //.jpg  .png
    // 2) 将扩展名补全到上传文件的路径上'uploads/avatar/' + newFilename
    let newName = filepath + extName;
    console.log(newName);
    // 3) 文件更名操作
    fs.renameSync(filepath, newName);
    // 4) 获取更名文件的相对地址
    let url = '/uploads/news/' + newFilename + extName;

    //将更新后的地址返回给我前端
    res.json({
      code: 200,
      data: {
        newsPic: url
      },
      msg: '头像修改成功'
    })
  })
})
router.get('/newsSelect', async (req, res) => {
  let sql = `select id,title, pubdate, author, content,newsPic, addtime from news`;
  let data = await mysql.query(sql);

  if (data.length > 0) {
    //更新成功后信息也需要返回给前端
    res.json({
      code: 200,
      data,
      msg: '新闻查询成功'
    });
  } else {
    res.json({
      code: 201,
      data: null,
      msg: '暂无新闻'
    });
  }
})
router.get('/detail', async (req, res) => {
  let id = req.query.id;
  console.log(id);
  let sql = `select title, pubdate, author, content,newsPic, addtime from news where id=${id}`;
  let data = await mysql.query(sql);

  if (data.length > 0) {
    //更新成功后信息也需要返回给前端
    res.json({
      code: 200,
      data,
      msg: '新闻查询成功'
    });
  } else {
    res.json({
      code: 201,
      data: null,
      msg: '暂无新闻'
    });
  }
})








//登录注册
router.post('/register', async (req, res) => {

  let {
    username,
    password
  } = req.body;

  if (!username || !password) {
    res.json({
      code: 208,
      data: null,
      msg: '账号或密码不能为空'
    });
    return;
  }

  //检查是否注册
  let a = await mysql.query(`select * from e_member where username=?`, [username]);
  // console.log(a);
  //先查询数据库看该用户名是否存在  存在提示用户名已存在  不存在添加
  if (a.length > 0) {
    // res.send('用户名已存在');
    res.json({
      code: 20002,
      data: null,
      msg: '该账号已注册'
    });
    console.log('该账号已注册');
    return;
  }

  //继续注册流程
  let mid = uuid.v1();
  let newpwd = md5(password + secret);
  let [err, result] = await to(mysql.query('insert into e_member(mid,username,password,createdate) values(?,?,?,?)', [mid, username, newpwd, Date.now()]));
  // console.log(err);
  if (!err) {
    if (result.affectedRows > 0) {
      res.json({
        code: 200,
        data: null,
        msg: '注册成功'
      });
      return;
    } else {
      res.json({
        code: 201,
        data: null,
        msg: '注册失败'
      });
      return;
    }
  } else {
    res.json({
      code: 500,
      data: err,
      msg: '数据库查询失败'
    });
  }

})

//登录
router.post('/login', async (req, res) => {
  let {
    username,
    password
  } = req.body;

  if (!username || !password) {
    res.json({
      code: 208,
      data: null,
      msg: '账号或密码不能为空'
    });
    return;
  }
  let sql = `select mid,realname,username,birthdate,sex,head_photo_url from e_member where username=? and password=?`;
  let newpwd = md5(password + secret);
  let [err, result] = await to(mysql.query(sql, [username, newpwd]));
  console.log(result);
  if (!err) {
    if (result.length > 0) {
      let payload = {
        exp: Date.now() + 1000 * 60 * 60 * 24
      }; //设置jwt过期时间

      let token = jwt.sign(payload, secret);
      //登陆成功后,用户的token,昵称,性别,生日,头像等信息一般会返回给客户端
      let [{
        mid,
        realname,
        username,
        birthdate,
        sex,
        head_photo_url
      }] = result;

      res.json({
        code: 200,
        data: {
          token,
          data: {
            mid,
            realname,
            username,
            birthdate,
            sex,
            head_photo_url
          }
        },
        msg: '登陆成功'
      });

    } else {
      res.json({
        code: 20001,
        data: null,
        msg: '账号或密码错误'
      });
    }
  } else {
    res.json({
      code: 500,
      data: err,
      msg: '数据库查询失败'
    });
  }
})


//token验证
router.use(intercept());
//获取会员信息
router.get('/user', async (req, res) => {
  let mid = req.query.mid;
  let sql = `select mid,realname,username,sex,birthdate,head_photo_url,createdate from e_member where mid=?`;
  let a = await mysql.query(sql, [mid]);
  res.json({
    code: 200,
    data: a[0],
    msg: '会员信息获取成功'
  })
})



//更新会员信息
router.put('/user', async (req, res) => {
  let {
    mid,
    realname,
    username,
    sex,
    birthdate
  } = req.body;
  if (!mid || !username) {
    res.json({
      code: 201,
      data: null,
      msg: 'mid或账号不能为空'
    })
  }

  let sql = `UPDATE e_member set realname=?,username=?,sex=?,birthdate=? where mid=?`;
  let a = await mysql.query(sql, [realname, username, sex, birthdate, mid]);

  if (a.affectedRows > 0) {
    //更新成功后信息也需要返回给前端
    res.json({
      code: 200,
      data: {
        realname,
        username,
        sex,
        birthdate,
        mid
      },
      msg: '用户信息更新成功'
    });
  } else {
    res.json({
      code: 201,
      data: null,
      msg: '用户信息更新失败请检查参数'
    });
  }

})

//更新用户头像
router.put('/uploadhead', (req, res) => {
  //初始化 设置上传文件的存放目录
  let form = formidable({
    uploadDir: './uploads/avatar',
    // maxFields: 1024 * 200  设置上传文件大小
  });
  form.parse(req, async (err, fields, files) => {
    // console.log(fields, files);
    //如果出错结束代码
    if (err) {
      res,
      json({
        code: 500,
        data: err,
        msg: '上传失败请重试'
      })
      return;
    }
    let {
      mid
    } = fields;
    let {
      userphoto: {
        filepath,
        newFilename,
        originalFilename
      }
    } = files;

    // 1) 从原始文件中提取扩展名
    let extName = path.extname(originalFilename); //.jpg  .png
    // 2) 将扩展名补全到上传文件的路径上'uploads/avatar/' + newFilename
    let newName = filepath + extName;
    console.log(newName);
    // 3) 文件更名操作
    fs.renameSync(filepath, newName);
    // 4) 获取更名文件的相对地址
    let url = '/uploads/avatar/' + newFilename + extName;
    // 5) 更新数据库中head_photo_url字段的值
    let sql = `update e_member set head_photo_url=? where mid=?`;
    let a = await mysql.query(sql, [url, mid]);
    console.log(a);
    if (a.affectedRows > 0) {
      //将更新后的地址返回给我前端
      res.json({
        code: 200,
        data: {
          head_photo_url: url
        },
        msg: '头像修改成功'
      })
    } else {
      res.json({
        code: 201,
        data: null,
        msg: '头像修改失败,请检查参数'
      })
    }
  })

})


//用户学习记录接口
router.get('/orders', async (req, res) => {
  let {
    mid,
    page,
    pagesize
  } = req.query;

  let start = (parseInt(page) - 1) * parseInt(pagesize);

  console.log(start, page, pagesize);
  let sql = `SELECT
	e_course.cid,
	e_course.title,
	e_course.price,
	concat( '/uploads/course/', e_course.image_src ) AS image_src,
	e_course.type_name,
	e_course.area_name,
	e_course.grade_name,
	e_course.subject_name,
	e_course.category_name
FROM
	e_order
	INNER JOIN e_course ON e_order.cid = e_course.cid 
WHERE
	e_order.mid =?
  limit ?,?`;
  //分页
  let sql2 = `SELECT count(*) as totalNum
    FROM e_order
    INNER JOIN e_course ON e_order.cid = e_course.cid 
    WHERE e_order.mid =?`;

  /* Promise.all([
    db.query(sql, [mid, start, pagesize]),
    db.query(sql2, [mid])
  ]) */

  //查询的结果
  let a = await mysql.query(sql, [mid, start, parseInt(pagesize)]);

  //总记录数
  let [{
    totalNum
  }] = await mysql.query(sql2, [mid]);


  res.json({
    code: 200,
    data: {
      page: parseInt(page),
      pagesize: parseInt(pagesize),
      totalNum,
      result: a
    },
    msg: '学习记录成功'
  })

})



module.exports = router;

tools  工具

config.js   数据库配置

let options = {
    host: "127.0.0.1", //连接数据库服务器地址,ip地址或者域名
    port: 3306, //端口
    user: "root", //管理员账号
    password: "root", //管理员密码
    database: "xiaoucourse" //要操作的数据库名
}

let secret = 'hsdhsihdsh';

module.exports = {
    options,
    secret
};

db.js   数据库连接

let mysql = require('mysql');
let {
    options
} = require('./config');

//1.创建连接对象
let conn = mysql.createConnection(options);
//2.尝试连接数据库
conn.connect((err) => {
    if (err) {
        console.log("连接数据库失败", err);
        return;
    }
})
//3.执行crud操作
function query(sql, arr) {
    return new Promise((resolve, reject) => {
        conn.query(sql, arr, (err, results) => {
            // err 执行crud操作时的错误消息
            // results 执行crud操作后的结果
            if (!err) {
                resolve(results); //修改Promise状态为成功并返回结果
            } else {
                reject(err); //修改Promise状态为失败并返回错误
            }
        })
    })
}
// query('select * from 班级 where id=?', [8]);
//4.断开连接释放资源
function close() {
    conn.end();
}

module.exports = {
    query,
    close,
}

intercept.js  校验token

// intercept.js
let jwt = require("jsonwebtoken");
let {
    secret
} = require("./config");

function intercept() {
    return (req, res, next) => {
        // 1、验证token是否为空
        let {
            token = ""
        } = req.headers;
        if (!token) {
            res.json({
                code: 201,
                data: null,
                msg: "token为空,请登录后访问"
            });
            return;
        }
        // 2、验证token是否有效
        jwt.verify(token, secret, (err, decoded) => {
            console.log(token);
            if (!err) {

                // 3、检查token是否在有效期内
                if (Date.now() > decoded.exp) {
                    // token已过期了
                    res.json({
                        code: 208,
                        data: null,
                        msg: "token已过期,请重新登录"
                    });
                    return
                } else {
                    // 一切正常
                    next();
                }
            } else {
                res.json({
                    code: 208,
                    data: null,
                    msg: "token无效"
                });
                return;
            }
        })
    }
}
module.exports = intercept;

to.js

//promise对象错误消息处理
//作用:将参数(promise对象)的then()或者catch()返回结果包装成一个数组返回
function to(promise) {
    return promise.then((data) => {
        return [null, data];
    }).catch((err) => {
        return [err];
    });
}

module.exports = to;

 静态文件及MySQL数据库文件连接

链接:https://pan.baidu.com/s/13JYqoqxAdeC_ElS7y4f8dA?pwd=qh27 
提取码:qh27

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只大菜鸟J

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值