简介
前面我们实现了登入登出,一切看上去是没有什么问题,但是如果我们试着在登录情况下刷新一下页面。
头部显示变成了未登录的情况,如果每次刷新或者进入新的页面用户都需要重新登录,明显是不友好的,我们需要在用户登录以后保持登录态一段时间。可是,http本身又是无状态无连接的,此时我们需要借助cookie和session。关于这两者的详细知识我今后会开单章说明,不明白的同学可以先网上搜集一些资料看看。
本节主要有如下工作:
- 保持登录态
- 登出逻辑实现
1. 保持登录态
step1 在server端下载express-session包
npm install express-session --save
step2 在server端引入并使用express-session
修改app.js文件如下:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var goodsRouter = require('./routes/goods');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
// session需要在定义路由前使用
app.use(session({
secret: 'six-tao',
name: 'ST-TOKEN',
cookie: {maxAge: 5 * 60 * 1000},
resave: true,
saveUninitialized: false
}))
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/goods', goodsRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
step3 修改users.js逻辑
在login接口中,增加登陆成功后将doc保存到req.session.user的逻辑,增加登录状态判断逻辑。如下:
var express = require('express');
var router = express.Router();
var User = require('../models/user');
/* post users info. */
router.post('/login', function (req, res, next) {
console.log(req.body);
let param = {
userName: req.body.userName,
userPwd: req.body.userPwd
};
if (req.session.user) {
res.json({
code: '101',
msg: '您已登录'
});
return;
}
User.findOne(param, function (err, doc) {
if (err) {
res.json({
code: '900',
msg: err.message || '服务器错误'
})
} else {
if (doc) {
req.session.user = doc
res.json({
code: '000',
msg: '',
result: {
userName: doc.userName
}
});
} else {
res.json({
code: '102',
msg: '用户名或密码错误'
});
}
}
});
});
router.get('/checkLogin', function (req, res, next) {
console.log(req.session.user)
if (req.session.user) {
res.json({
code: '000',
msg: '',
result: req.session.user
});
} else {
res.json({
code: '102',
msg: '未登录',
});
}
})
module.exports = router;
step4 修改前端逻辑
在main.js中增加登录状态判断逻辑:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import axios from 'axios'
import VueLazyLoad from 'vue-lazyload'
import './assets/css/base.css'
import './assets/css/login.css'
import './assets/css/product.css'
Vue.config.productionTip = false
Vue.use(VueLazyLoad, {
loading: '../static/loading/loading-bars.svg',
error: '../static/ok-2.png'
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: ' ',
created () {
this.checkLogin()
},
methods: {
checkLogin () {
axios.get('/api/users/checkLogin').then(res => {
let data = (res && res.data) || {}
if (data.code === '000') {
let result = data.result || {}
this.$store.commit('LOG_IN', {userName: result.userName})
}
})
}
}
})
我们检测一下结果:
跳登录页,输入错误的账号密码:
输入正确的账号密码:
登录状态下刷新:
2. 登出逻辑实现
之前我们把登出逻辑放在前端。我们看一下:
刷新以后会出现问题。我们把登出的前后端逻辑补齐。
step1 后端逻辑
在users.js增加如下代码:
router.post('/logout', function (req, res, next) {
req.session.destroy();
res.json({
code: '000',
msg: '登出成功'
});
});
step2 前端逻辑
修改PageHead.vue的logout方法如下
logout () {
axios.post('/api/users/logout').then(res => {
let data = (res && res.data) || {}
if (data.code === '000') {
this.$store.commit('LOG_OUT')
}
})
}
我们重新运行项目,并登陆以后:
总结
到这里,我们的登录逻辑就算基本完成了。当然,真实的项目中,逻辑不止这么简单。比如我们这里的密码使用明文存储,是非常危险的,密码应该加密加盐处理。另外,我们重启服务器的时候session失效了,可以将session放在redis或者mongodb中进行存储。等等。
我们提交一下代码:
- six-tao
git status
git diff
git commit -am 'add checkLogin and logout'
git push
- six-tao-server
git status
git diff
git commit -am 'add session, checkLogin and logout'
git push