步骤一:现在后端tools.js文件中构造生成JWT数据以及使用JWT数据模块
数据 | 含义 |
jwt.sign(自定义数据,密钥,{选项}) | |
expiresIn | 数据存储时间 |
uid | 已经登陆的用户id |
usernam | 已经登陆的用户名 |
let curKeys = 'qweiotriqu1'; //密钥
module.exports.createJWT = function (uid,username) {
return jwt.sign({ uid, username }, curKeys, { expiresIn: 60 * 60 * 2 });
}
//使用JWT数据:jwt.verify(jwt数据,密钥)
module.exports.useJWT = function(jwtData) {
try {
let obj = jwt.verify(jwtData, curKeys);
if (obj) {
return obj;
} else {
return false;
}
} catch (e) {
return false;
}
}
步骤二:前端将uid和username传递给后端接口,在这里利用步骤一的模块生成JWT数据,并返回给客户端,此时客户端会将JWT数据储存到localStorage中
let sql = `select password,mid from e_member where username='${uname}'`;
let [err, arr] = await execSql(sql);
if (err) {
if (arr.length == 0) {
res.send(Msg(500, '帐号不正确'));
return;
}
//判断密码是否正确:
if (arr[0].password == md5(pwd)) { //登录成功
//JWT:登陆成功后生成JWT数据并返回给客户端:
let jwtData = createJWT(arr[0].mid, uname);
console.log(jwtData);
res.send(Msg(200, '登录成功', [{ jwtData }]));
} else { //密码错误
res.send(Msg(500, '密码错误'));
}
} else {
res.send(Msg(500, '帐号查询失败'));
}
步骤三:前端的登陆页面,在登陆成功后将服务端生成的JWT数据保存到客户端localStorage中;
$('.loginbtn').click(async function () {
//获取账号
let uname = $("#tel").val();
//获取密码
let pwd = $("#pass").val();
let [err, obj] = await sendAjax('/login', 'post', {
uname,
pwd
});
if (err) {
alert(obj.msg);
if (obj.status == 200) {
//登陆成功
//登陆成功后将服务端生成的JWT数据保存到客户端localStorage中
localStorage['curJWTData'] = obj.data[0].jwtData;
console.log('成功了');
//页面跳转
// location.href = '../../index.html';
}
} else {
console.log('登陆接口调用失败');
}
});
步骤四:在前端渲染页面时,从本地localStorage提取JWT数(例如查看当前登陆用户的报名课程)
//每页要显示的条数
let limits = 4;
//第几页
let pages = 1;
//我的课程渲染
async function myCourse(){
//从本地localStorage获取JWT数据
let jwtData = localStorage['curJWTData'] ? localStorage['curJWTData'] : '';
if(jwtData == ''){
alert('请先登陆');
location.href= './loginAndRegister/login.html';
return;
}
console.log(jwtData);
let [err, obj] = await sendAjax('/myCourse','get',{
jwtData, //向后端接口传递jwt数据,jwt数据里面由uid和username
limits,
pages
});
if(err){
let arr = obj.data;
console.log(obj.data);
let str = '';
for(let i = 1; i < arr.length; i++){
str += `<li>
//str具体内容省略
</li>`;
$('.lesson .clearfix').html(str);
//渲染分页信息
//pageInfo(arr[0]);
}
}else{
console.log('我的课程接口调用失败');
}
}
myCourse();
步骤5:后端课程接口接收前端发送数据
//我的课程接口 优化:支持分页
router.get('/myCourse', async (req, res) => {
//接收jwt数据
//jwtData:jwt数据
//limits:每一页要显示的条数
let { jwtData, limits = 4, pages = 1 } = req.query;
if (jwtData == '') {
res.send(Msg(501, '非法访问'));
return;
}
let userObj = useJWT(jwtData);
//userObj解析出来是一个对象,{ uid, username }
if (!userObj) {
res.send(Msg(501, '非法访问'));
return;
}
//查询我的课程(用户报名学习过的课程);
//limit: m,n
//n:每一页要显示的条数;
//m = (当前查看的第几页 - 1) * n
//pages:当前查看的第几页
//计算游标位置(m)
let start = (pages - 1) * limits;
let sql = `select c.cid,title,price,concat('${imgHost}course/',image_src)as image_src,subject_name,area_name from e_order as o left join e_course as c on o.cid=c.cid where mid='${userObj.uid}' limit ${start},${limits}`;
let [err, arr] = await execSql(sql);
console.log(arr, 1234512355);
if (err) {
//查询总的记录个数
sql = `select count(o.id)as n from e_order as o left join e_course as c on o.cid=c.cid where mid='${userObj.uid}' limit ${start},${limits}`;
let [flg, mArr] = await execSql(sql);
//mArr ——> [ RowDataPacket { n: 4 } ] (总个数);
if (flg) {
//将总的记录个数放在arr数组的头部;
arr.unshift(mArr[0].n);
} else {
arr.unshift(0);
}
res.send(Msg(200, '我的课程查询成功', arr));
} else {
res.send(Msg(500, '我的课程查询失败'));
}
});