数据模型
主要用户名,密码,邮箱,头像,身份
const mongoose = require('mongoose') const schema = new mongoose.Schema({ username: { type: String, require: true }, email: { type: String, require: true }, password: { type: String, require: true }, avator: { type: String }, identify:{ type: Number, require: true }, createdAt: { type: String, default: Date.now() }, updateAt: { type: String, default : Date.now() } }) module.exports = mongoose.model('user', schema)
首先注册接口代码
router.post('/register', async ctx => { const {username, password, email, avatar, identify} = ctx.request.body try { const user = await UserModel.findOne({email}) if (user) { return ctx.body = {code: 1, msg: '邮箱存在'} } const newUser = new UserModel({username, password, email, avatar, identify}) const res = await newUser.save() return ctx.body = {code:0, data: res } } catch(err) { return ctx.body = {code:0, msg: '出错啦'} } })
首先对密码进行加密加盐
加密方案1
utility进行字符串加密
const utility = require('utility') exports.md5 = pwd => { const salt = '!@#$%' return utility.md5(pwd + salt) }
const newUser = new UserModel({username, email, avatar, identify, password: md5(password)})
登录接口代码
router.post('/login', async ctx => { const {email, password} = ctx.request.body const res = await UserModel.findOne({email}) if (!res) return ctx.body = {code: 1, msg:'用户不存在'} if (res.password !== md5(password)) return ctx.body = {code:1, msg: '密码错误'} const user = {username: res.username, email: res.email, identity: res.identify, avator: res.avatar} return ctx.body = {code: 0 , data: user} })
安装jwt
jsonwebtoken
返回token
const token = await jwt.sign({username: user.username, id: user._id, email: user.email, timeout: `${(new Date().getTime() + 60*60*10)}`}, config.secret, {expiresIn: 3600}) return ctx.body = {code: 0 , data: Object.assign(user, {token: `Bearer ${token}`})}
使用koa中间件机制检测用户是否登录或者token是否过期
const jwt = require('jsonwebtoken') const UserModel = require('../db/models/user') const config = require('../config/config') const check = async (ctx, next) => { const url = ctx.request.url // 登录,注册不做token校验 if (url === '/user/login' || url === '/user/register') await next() else { const token = ctx.request.headers['authorization'].split(' ')[1] // 解析token const payload = await jwt.verify(token, config.secret) const date = new Date().getTime() const {email, timeout} = payload if (date > parseInt(timeout)) return ctx.body = {code: 11, msg: 'token过期'} // 查询用户是否存在 const user = await UserModel.findOne({email: email}) if (!user) return ctx.body = {code: 10, msg: '用户没有登录'} else await next() } } module.exports = check
Vue前端
登录之后获得token存储到本地,并且解析token把用户信息存储到Store中
const user = jwtDecode(token) window.localStorage.setItem('token', token) this.setUser(user) this.setIsAutnenticated(!isEmpty(user)) this.$router.push('/')
路由守卫
根据本地是否有token判断用户是否登录
router.beforeEach((to, from, next) => { const isLogin = !!window.localStorage.getItem('token') if (to.path === '/login' || to.path === '/register') next() else { isLogin ? next() : next({ name: 'login' }) } })
请求拦截
把token发生给服务器
axios.interceptors.request.use(config => { // 添加Loading startLoading() const token = window.localStorage.getItem('token') if (token) { config.headers['authorization'] = token } return config }, err => { return err })