
很久之后才更新,一个是比较忙,还有就是不知道还要介绍啥,最近有小伙伴问我,怎么鉴权之类的,我就分享一下我的鉴权。
项目结构
先看看项目结构
├── build # webpack文件,配置参数,打包的代码存放在这里。
├── config # vue项目的基本配置文件
├── node_modules # 项目中安装的依赖模块
├── src # 源代码文件夹
└── api # 请求接口文件
└── components # 放置各个vue组件文件
└── pages # 各个页面文件
└── store # 项目的状态管理文件,包括登录,用户信息和token等
└── style # 项目公共样式
└── utils # 项目公用的js文件
└── app.json # 小程序的app.json
└── App.vue # App.vue组件,项目入口文件
└── main.js # 项目的核心入口文件
├── static # 静态资源目录,如图片、字体等
└── images # 登录加密配置文件
├── .babelrc # babel编译参数,vue开发需要babel编译
├── .editorconfig # 代码编辑环境配置文件
├── .eslintignore # eslint检查忽略文件
├── .eslintrc.js # eslint检查配置文件
├── .gitignore # git提忽略文件
├── .postcssrc.js # css配置文件,自动补齐浏览器css前缀
├── index.html # 主页,项目入口文件
├── package.json # 项目配置文件,,描述项目信息和依赖
├── README.md # 项目的说明文档,markdown 格式
Vuex的使用
首先安装vuex
npm install vuex -S
创建store
创建好store目录后,和普通vue的项目一样,使用vuex
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user
},
state: {
count: 0
},
mutations: {
increment: (state) => {
const obj = state
obj.count += 1
},
decrement: (state) => {
const obj = state
obj.count -= 1
}
}
})
export default store
将store挂载到Vue上

配置要做状态管理的内容
我的token信息就是存在user里,利用小程序的storage来做持久化
const user = {
state: {
token: mpvue.getStorageSync('token'),
userinfo: mpvue.getStorageSync('user')
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_USER: (state, user) => {
state.userinfo = user
}
}
}
和普通vue项目的使用完全一样
在template里直接$store.state.user.token就可以直接获取到,当然你也可以写getter来方便获取
在js里也是一样 this.$store.state.user.token 也是可以直接获取到
当然mapState也可以使用
import { mapState } from 'vuex'
export default {
computed: {
...mapState({
userinfo: state => state.user.userinfo
})
}
}
配置apiconfig,请求数据的鉴权
首先引入store
import store from '@/store'
请求拦截
对请求进行拦截处理,这个之前讲flyio的时候也说过
// 添加请求拦截器
fly.interceptors.request.use(config => {
const token = store.state.user.token
// console.log(token)
// 给所有请求添加自定义header
config.headers['token'] = token
if (config.headers['Content-Type'] !== 'application/json') {
config.body = qs.stringify(config.body)
}
// 可以显式返回request, 也可以不返回,没有返回值时拦截器中默认返回request
return config
}, error => {
Promise.reject(error)
})
响应的鉴权拦截
因为小程序首次授权后,再次进入的时候可能会停留在上次进入的页面,如果这个时候token已经失效,应该不让用户知道,偷偷的登录
let reqCount = 0
// 响应拦截器
fly.interceptors.response.use(async response => {
// 同意处理一些响应的code状态
// do sthing
// 只将请求结果的data字段返回
console.log(response, response.request)
// 判断是否有响应,与后台进行统一,如果是token失效过期之类的,就进入以下方法
if (response.data && response.data.code === '00000') {
// 重新登录,并且记录请求登录的次数,登录3次后仍失败,跳转到授权登录页面
reqCount += 1
if (reqCount < 3) {
let data = await store.dispatch('wxLogin').then(async () => {
// 登录成功后,重新发起之前的请求拿到数据,返回
let res = await fly.request(response.request).then(res => res)
reqCount = 0
return res
})
} else {
mpvue.redirectTo({
url: '/pages/login'
})
}
return data
} else {
return response.data
}
},
(err) => {
// 发生网络错误后会走到这里
wx.getNetworkType({
success: res => {
console.log(res)
if (res.networkType === 'none') {
wx.showToast({
title: '当前网络不可用,请检查你的网络设置',
icon: 'none',
duration: 2000
})
} else {
wx.showToast({
title: '服务器繁忙,请稍候再试',
icon: 'none',
duration: 2000
})
}
}
})
console.log(err)
})、
小程序的授权判断
由于mpvue的进入都会从App.vue进入,所以我把授权写在App.vue里
mounted () {
// 获取用户授权状态
mpvue.getSetting({
success: (res) => {
// 如果没有授权的话,管他三七二十一,跳转到登录授权页面,让他去授权
if (res.authSetting['scope.userInfo'] === undefined) {
if (this.$router.currentRoute && this.$router.currentRoute.path !== '/pages/login') {
mpvue.navigateTo({
url: '/pages/login'
})
return false
}
} else if (res.authSetting['scope.userInfo'] !== undefined && res.authSetting['scope.userInfo'] !== true) {
console.log('拒绝授权')
} else {
// console.log('已授权')
// 已经授权,就调后台的登录接口,进行登录
this.$store.dispatch('wxLogin').then(() => {
// 判断当前进行登录的动作发生的页面,如果是登录授权页,就跳转到首页,否则留在当前页面
if (this.$router.currentRoute && this.$router.currentRoute.path === '/pages/login') {
mpvue.switchTab({
url: '/pages/index'
})
}
})
}
},
fail: res => {
console.log(res)
}
})
}