上篇文章使用了bcryptjs对密码进行了加密,既然加密后的密码是不可逆的,那么保存后的密文又如何被验证识别呢?
仍然使用bcryptjs,其中的compareSync来比较密码和数据库的密文。
1.制作登陆页面
登陆页面不使用Main.vue带有左侧菜单的布局,所以与Main.vue的路由链接“/”同级。
Login.vue:
<template>
<div class="login-container">
<el-card header="管理员登录" class="login-card">
<!-- 监听表单的submit事件,native.prevent监听原生表单事件跳转接口并且阻止页面跳转 -->
<el-form @submit.native.prevent="login">
<el-form-item label="用户名">
<el-input v-model="model.username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="model.password" type="password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" native-type="submit">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
export default {
data() {
return {
model: {}
}
},
methods: {
async login() {
const res = await this.$http.post('login')
console.log(res)
}
}
}
</script>
<style>
.login-card{
width: 35rem;
margin: 6rem auto;
}
</style>
2.写登录接口
server/routes/admin/index.js:
// 登录接口
app.post('/admin/api/login', async(req, res) => {
// 将接收到的username和password解构
const { username, password } = req.body
// 1.根据用户名找用户
// 如果用户名为空
if(!username){
return res.status(422).send({
message: '请输入用户名'
})
}
// 引入model模型
const Admin = require('../../models/Admin')
// 利用模型查找指定用户,同时将密码连带查询出来
const user = await Admin.findOne({
username: username
}).select('+password')
if(!user){
// 如果没有该用户,返回一个非500\404的错误码,同时发送查询结果不存在的信息
return res.status(422).send({
message: '用户不存在'
})
}
// 2.校验密码
if(!password){
return res.status(422).send({
message: '请输入密码'
})
}
// 引入bcryptjs,用来比较密码和密文是否匹配(前端传入的password,后端查询数据库的password)
const isValid = require('bcryptjs').compareSync(password, user.password)
// 如果密码与密文不匹配
if(!isValid){
return res.status(422).send({
message: '密码错误'
})
}
// 3.返回token
// 如果密码与密文匹配
return ..
})
测试:
3.全局监听响应的拦截,将错误时发送的message在页面显示
admin/src/http.js:
// 全局进行响应的拦截(axios内的响应拦截方法)
http.interceptors.response.use(res => {
return res
},err => {
// 如果拦截到错误的操作,使用VUE将错误信息进行弹出展示
// 获取错误信息console.log(err.response.data.message)
Vue.prototype.$message({
type: 'error',
message: err.response.data.message
})
return Promise.reject(err)
})
4.使用jsonwebtoken创建token值进行登录
密码验证成功后,我们就向admin端发送一个token值,像session一样挂载到网页,如果有token值就可以进入admin页面,没有就需要进行登录。
(1)使用token
cd server
npm i jsonwebtoken
在server/routes/admin/index.js登录接口第三步,生成密钥处编写:
server/index.js全局定义密钥:
此时,点击登录token值就可以生成,并发送到web端:
(2)存储token并跳转admin管理页面
Login.vue编辑login接口回调:
测试:
登陆成功。
且token值已保存:
5.token验证
此时我们已经完成了管理员登录功能的实现,但是就算不登陆也可以访问admin端页面,下篇文章我们使用token进行登陆的校验,实现进入页面必须登录的操作。