Vue+Vant+Koa2+MongoDB 实现用户登陆
Posted 几行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue+Vant+Koa2+MongoDB 实现用户登陆相关的知识,希望对你有一定的参考价值。
前面的文章介绍了 Vue + Vant + koa2 + MongoDB 实现用户注册,今天我们来讲解一下用户登陆的实现。
主要实现:
1、前端通过 axios 向后端发送 username、password
2、后端检查用户名是否已注册、比对 password 是否正确。
3、后端生成 JWT 令牌返回给前端,前端存储于 localStorage 中。
其中,图形验证码部分将在下一节中讲解。
效果截图:
登陆成功,返回 code:200 msg : 登陆成功,并打印出 token
未注册用户返回:
密码错误返回:
JWT简介:
JWT 全称 JSON WEB TOKEN ,是目前最流行的跨域认证解决方案,假设用户登陆成功之后,首先访问 A 页面,然后访问 B 页面,而这两个页面的内容都需要根据用户的身份来获取,比如说 A 页面为用户的订单列表,需要根据 user_id 来查询该用户的所有订单,B 页面为用户的收货地址列表,又需要根据 user_id 字段来查询该用户的地址列表,而在不同页面之间,这个 user_id 是如何传递的呢,首先我们可以利用session ,服务端通过 cookie 将 session 发送给客户端,这种方式是将 session 存储于服务端,还有一种方式就是服务端通过 jwt 将 user_id、username 等信息生成加密的 token ,客户端接收之后将其存储于LocalStroage ,这样当用户访问 B 页面地址时,配置请求的 header 访问头,将 token 添加进请求头,服务端收到 token 进行解析,即可解析出 user_id、username 等信息,从而获取出 user_id ,从而 B 页面就会根据 user_id 获取到该用户的地址列表。
另外,cookie 方式不支持跨域,JWT 支持跨域认证,例如单点登录就是依靠 JWT 实现。
一、前端部分
于.\\vue-mall-mobile\\mall\\src 新建 Login.vue,采用 Vant 的表单控件 :
<template> <div id="login"> <van-form> <van-field v-model="username" label="账号" /> <van-field v-model="password" type="password" label="密码" /> <van-button square block type="info" native-type="submit" size="normal" @click="Login"> 登陆 </van-button>
</van-form> </div> </template> <script> import { Field } from \'vant\'; import { Button } from \'vant\'; import { Toast } from \'vant\'; import { Form } from \'vant\'; import ajax from \'@/api\';
export default { components:{ [Field.name]: Field, [Button.name]: Button, [Toast.name]: Toast, [Form.name]: Form, }, data() { return { username:\'\', password:\'\', } } } </script>
mothods 中添加 Login() 方法:
async Login() { let { username, password} = this.$data; let res = await ajax.login(username, password); console.log(res) }
在 src\\api\\index.js 中添加,通过 axios 将 username、password 发送到后端接口:
login(username = \'\', password = \'\') { return axios.post(\'localhost:3000/users/loginUser\',{username, password}) }
二、后端部分:
在后端 routes\\users.js 中添加响应路由:
/** * 用户登陆 */ router.post(\'/loginUser\', async function (ctx) { let {username, password} = ctx.request.body; if(!username || !password) return ctx.body = {code: 4020,msg: \'请填写完整的注册信息\'}; let args = {username, password}; const userData = await userService.accountLogin(args); ctx.body = (userData.code === 200) ? {code: 200, msg: \'登陆成功\', token: jwt._createToken(userData)} : userData })
在 service\\userService 中添加处理登陆方法 accountLgoin({ username, password }) :
async accountLogin({username, password}) { const userDoc = await UserModel.findOne({username}); if(!userDoc) return {code: 0, msg: \'该用户尚未注册\'}; let result = await userDoc.comparePassword(password, userDoc.password); // 进行密码比对是否一致 return !result ? { code: -2, msg: \'密码不正确\' } : { code: 200, _id: userDoc._id, userName: userDoc.userName, gender: userDoc.gender, avatar: userDoc.avatar, mobilePhone: userDoc.mobilePhone, email: userDoc.email, year: userDoc.year, month: userDoc.month, day: userDoc.day }; }
这里的 userDoc.comparePassword() 方法,是我们在定义 UserModel 是添加的方法,bcryptjs 的 bcrypt.compare() 方法来实现对比我们在输入框中输入的秘密和保存在数据库里的 hash 处理后的密码。
生成 JWT 令牌,\\utils\\jwt.js 中的 _createToken() 方法:
const jwt = require(\'jsonwebtoken\'); /** * 创建 Token */ const _createToken = (userInfo) => { // JWT 格式 token | 有效时间 1 小时 return jwt.sign({ userInfo }, secret, { expiresIn: \'1h\' }); };
这里的 { userInfo } 存储了用户的 id、username、性别等信息,以 token 令牌的方式存储于客户端,也就是前端,等到客户端发送请求时,在 header 请求头中,加入该 token,后端通过 jwt.virefy() 将 token 中存储的信息解析出来,解析方法如下,从而使后端代码可以通过解析出来的信息认定用户的身份。
const _verify = (token) => { return jwt.verify(token, secret, (error, decoded) => { console.log(decoded); }); };
三、前端储存 token
方法一:可以直接在 axios 返回时,用 localStorage.setItem() 将 token 写入,
localStorage.setItem(USER_TOKEN, JSON.stringify(userToken));
这样,我们下次想要访问该 token 时,直接:
JSON.parse(localStorage.getItem(USER_TOKEN))
不过我们应该熟悉 Vuex 状态管理,为后续开发中大型应用做准备,方法二:
在 axios 返回时,调用 this.$store.commit()
(res.token)&&(this.$store.commit(\'setUserToken\', res.token));
setUserToken 位于 .\\src\\store\\index.js :
export default new Vuex.Store({ state: { token: \'\', }, mutations: { setUserToken(state, token) { alert(token); state.token = token; } }, }
到这里,完整的登陆功能就实现啦。下一节我们会实现图片验证码。
如果文章中有错误之处,欢迎大家交流指正。
以上是关于Vue+Vant+Koa2+MongoDB 实现用户登陆的主要内容,如果未能解决你的问题,请参考以下文章
vue koa2 mongodb 从零开始做个人博客 登录注册功能后端部分