17-vue零基础到实战-注册和登录页面「渡一教育」( 五 )


在server文件夹 , 下面新建/token(文件夹)里面新增checkToken.js和createToken.js , 分别放置检查和新增token的方法 。
安装
$ cnpm i jsonwebtoken -ScreateToken.jsconst jwt = require('jsonwebtoken');module.exports = function(user_id){ const token = jwt.sign({user_id: user_id}, 'zhangzhongjie', {expiresIn: '60s' }); return token;};创建token时 , 我们把用户名作为JWT Payload的一个属性 , 并且把密钥设置为‘zhangzhongjie',token过期时间设置为60s 。意思是登录之后 , 60s内刷新页面不需要再重新登录 。
checkToken.js
const jwt = require('jsonwebtoken');//检查token是否过期module.exports = async ( ctx, next ) => { //拿到token const authorization = ctx.get('Authorization'); if (authorization === '') { ctx.throw(401, 'no token detected in http headerAuthorization'); } const token = authorization.split(' ')[1]; let tokenContent; try { tokenContent = await jwt.verify(token, 'zhangzhongjie');//如果token过期或验证失败 , 将抛出错误 } catch (err) { ctx.throw(401, 'invalid token'); } await next();};先拿到token再用jwt.verify进行验证 , 注意此时密钥要对应上createToken.js的密钥‘zhangzhongjie' 。如果token为空、过期、验证失败都抛出401错误 , 要求重新登录 。
数据库 mongodb
MongoDB是一种文档导向数据库管理系统 , 旨在为 WEB 应用提供可扩展的高性能数据存储解决方案 。用node链接MongoDB非常方便 。
安装
$ cnpm i mongoose -S
MongoDB的连接有好几种方式 , 这里我们用connection 。connection是mongoose模块的默认引用 , 返回一个Connetion对象 。
在server文件夹下新建db.js , 作为数据库连接入口 。
//db.jsconst mongoose = require('mongoose');mongoose.connect('mongodb://localhost/vue-login');let db = mongoose.connection;// 防止Mongoose: mpromise 错误mongoose.Promise = global.Promise;db.on('error', function(){ console.log('数据库连接出错!');});db.on('open', function(){ console.log('数据库连接成功!');});//声明schemaconst userSchema = mongoose.Schema({ username: String, password: String, token: String, create_time: Date});//根据schema生成modelconst User = mongoose.model('User', userSchema)module.exports = User;除了我们用的 connetion  , 还有 connect() 和 createConnection() 连接方式 。
Schema定义表的模板 , 让这一类document在数据库中有一个具体的构成、存储模式 。但也仅仅是定义了Document是什么样子的 , 至于生成document和对document进行各种操作(增删改查)则是通过相对应的model来进行的 , 那我们就需要把userSchema转换成我们可以使用的model , 也就是说model才是我们可以进行操作的handle 。
编译完model我们就得到了一个名为 User 的model 。
注意你在这里定义的schema表 , 后面写注册入库时数据的存储需要对应这个表 。
在server文件夹下新建controller(文件夹)/user.js,存放数据库的操作方法 。
先安装一些功能插件
$ cnpm i moment -s//用于生成时间$ cnpm i objectid-to-timestamp -s //用于生成时间$ cnpm i sha1 -s//安全哈希算法 , 用于密码加密//user.jsconst User = require('../db.js').User;//下面这两个包用来生成时间const moment = require('moment');const objectIdToTimestamp = require('objectid-to-timestamp');//用于密码加密const sha1 = require('sha1');//createTokenconst createToken = require('../token/createToken.js');//数据库的操作//根据用户名查找用户const findUser = (username) => { return new Promise((resolve, reject) => { User.findOne({ username }, (err, doc) => { if(err){ reject(err); } resolve(doc); }); });};//找到所有用户const findAllUsers = () => { return new Promise((resolve, reject) => { User.find({}, (err, doc) => { if(err){ reject(err); } resolve(doc); }); });};//删除某个用户const delUser = function(id){ return new Promise(( resolve, reject) => { User.findOneAndRemove({ _id: id }, err => { if(err){ reject(err); } console.log('删除用户成功'); resolve(); }); });};//登录const Login = async ( ctx ) => { //拿到账号和密码 let username = ctx.request.body.name; let password = sha1(ctx.request.body.pass);//解密 let doc = await findUser(username);if(!doc){ console.log('检查到用户名不存在'); ctx.status = 200; ctx.body = { info: false } }else if(doc.password === password){ console.log('密码一致!'); //生成一个新的token,并存到数据库 let token = createToken(username); console.log(token); doc.token = token; await new Promise((resolve, reject) => { doc.save((err) => { if(err){reject(err); } resolve(); }); }); ctx.status = 200; ctx.body = {success: true, username, token, //登录成功要创建一个新的token,应该存入数据库 create_time: doc.create_time }; }else{ console.log('密码错误!'); ctx.status = 200; ctx.body = { success: false }; }};//注册const Reg = async ( ctx ) => { let user = new User({ username: ctx.request.body.name, password: sha1(ctx.request.body.pass), //加密 token: createToken(this.username), //创建token并存入数据库 create_time: moment(objectIdToTimestamp(user._id)).format('YYYY-MM-DD HH:mm:ss'),//将objectid转换为用户创建时间 }); //将objectid转换为用户创建时间(可以不用) user.create_time = moment(objectIdToTimestamp(user._id)).format('YYYY-MM-DD HH:mm:ss'); let doc = await findUser(user.username); if(doc){console.log('用户名已经存在'); ctx.status = 200; ctx.body = { success: false }; }else{ await new Promise((resolve, reject) => { user.save((err) => { if(err){reject(err); }resolve(); }); }); console.log('注册成功'); ctx.status = 200; ctx.body = { success: true } }};//获得所有用户信息const GetAllUsers = async( ctx ) => { //查询所有用户信息 let doc = await findAllUsers(); ctx.status = 200; ctx.body = { succsess: '成功', result: doc };};//删除某个用户const DelUser = async( ctx ) => { //拿到要删除的用户id let id = ctx.request.body.id; await delUser(id); ctx.status = 200; ctx.body = { success: '删除成功' };};module.exports = { Login, Reg, GetAllUsers, DelUser};