1、在src目录下新建store目录,并在目录下新建index.js文件
2、参照Vuex的用法对登录中用户的token进行全局的定义和存储
import Vue from 'vue'
import vuex from 'vuex'
Vue.use(vuex)
export default new vuex.Store({
/**
* 公共数据存放区 */
state:{
Authorization: sessionStorage.getItem('Authorization') ? sessionStorage.getItem('Authorization'):'' //从sessionStorage中获取token,没有就默认为空
},
/**
* 修改数据要通过的mutations */
mutations:{
changeToken(state, token){
state.Authorization = token
sessionStorage.setItem('Authorization', token)
}
},
/**
* 获取数据可以用上的getters */
getters:{
getToken(state) {
return state.Authorization
}
},
/**
* 异步处理可能用上的actions */
actions:{
}
})
Vuex的导入及注册和vue-rouer一样。做一个不恰当的类比:state相当于组件中的data,mutations相当于组件中的methods,getters相当于组件中的computed。在state中我们定义存放token的字段"Authorization",并且用三元表达式为其赋值,sessionStarage为浏览器的一次会话的存储空间,会话结实就会清空;在mutations中我们定义一个方法"changeToken"来对token进行存放和赋值给state中的"Authorization"。
3、建立和定义好Vuex后要在main.js中对vuex进行全局的注册和实例化:
import store from './store/index'
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
到此,就可以在项目的任意地方对’Authorization’进行赋值和获取了。
//点击登录按钮执行访问请求并判断是否登陆
toHome(){
this.$axios({
method: 'post',
url: '/loginapp',
data: this.$qs.stringify({ //axios的post方法访问后端this.qs.stringify(
usename: this.usename,
password: this.password
}),
})
.then(res=>{ //请求成功后执行函数
if(res.data.msg === 'S'){
this.$store.commit('changeToken',res.data.token) //对token进行存储
this.$router.push('/home') //路由跳转到home界面
this.$notify({
title: '提示',
message: '用户登录成功',
duration: 3000
});
}else{
this.$notify({
title: '提示',
message: '用户登录失败',
duration: 3000
});
}
})
.catch(err=>{ //请求错误后执行函数
this.$notify({
title: '提示',
message: '用户访问错误',
duration: 3000
});
console.log(err)
})
}
}
这里贴出来的时登录的完整功能代码,通过res.data.token获取到服务器返回来的token,前面对vuex进行了全局的注册,在这里通过代码his.$store.commit(‘changeToken’,res.data.token) 实现对mutations中changeToken的调用,并且将token值传入,将token分别存入state和sessionStorage中供后面使用。
mutations:{
changeToken(state, token){
state.Authorization = token
sessionStorage.setItem('Authorization', token)
}
},
此处要是实现跳转到home页面时已经完成对服务器数据的加载和在页面上的渲染。首先用element-ui的table标签进行模板布局,在方法中调用axios的get方法向服务器发送请求,最终将请求的数据渲染在页面上:
在methods中定义getInfos方法请求服务器数据,同时用JSON.parse(res.data.infos)将数据转为json格式数据并赋值给template模板的table中绑定的tableData。要想实现载页面加载之前就在Dom中对表格渲染完成,需要将getInfos方法放入Vue生命周期函数created中。
至此我们可以是实现登录并且数据加载,如图:
但是也存在问题:
在浏览器的地址栏,直接输入http://localhost:8081/#/home就会跳过登陆界面直接进入home界面,显然这样是不安全,也是实际开发中不可为的,登录功能也就失去了他的意义。
对此,我们需要:
1.在每次页面跳转的时候对路由地址进行判定,如果是登录界面直接跳转过去,如果是其他页面,需要对用户的token进行判定,如果token和服务器的token一致,允许路由跳转,如果token为空或者与服务器的token不一致,阻止路由跳转并将页面跳转到登录页让用户登录;
2.对于用户每次请求服务器的数据的请求也要进行判定和用户信息验证。让用户的每次请求头中带上登录成功时存储在sessionStorage的’Authorization’对应的token,并且将用户携带的token和服务器中对应的用户token进行对比,验证通过返回用户请求的数据和通过标识;验证不通过返回让用户重新登录得标识;
因此,在页面进行跳转和请求之前,请求数据返回给用户之前进行拦截判定:
在main.js中调用axios.interceptors和router.beforeEach方法进行拦截和判定
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import axios from 'axios'
import qs from 'qs';
import router from './router/router'
import store from './store/index'
Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.prototype.$axios = axios
Vue.prototype.$qs = qs
//定义全局默认配置所有的请求头中都带上Authorization的token
axios.defaults.headers.common['Authorization'] = ''
new Vue({
router,
store,
render: h => h(App),
}).$mount('#app')
//所有求情发送出去之前要经过axios请求拦截器
axios.interceptors.request.use(
config => {
if(config.url != '/loginapp'){ //如果不是登录得请求
if(sessionStorage.getItem('Authorization')){ //判断浏览器中是否有token
config.headers.Authorization = sessionStorage.getItem('Authorization') //如果有token就带上token请求服务器数据
}else{
this.$router.push('/') //如果浏览器中没有token就跳转到登陆界面
}
}
return config;
},
err => {
return Promise.reject(err);
}
),
//所有求情的结果返回之前要经过axios响应拦截器
axios.interceptors.response.use(
res => {
if(res.data.msg === 'S'){ //如果服务器对用户验证通过返回“S”成功标签就将用户需要的数据传递给请求的地方
return res
}
},
err => {
err //如果服务器对用户验证不通过,清空浏览器中可能是失效了得token并跳转到登陆界面
sessionStorage.removeItem('Authorization');
this.$router.push('/');
}
),
//路由跳转之前进行判断
router.beforeEach((to, from, next) =>{
if(to.path === '/'){ //每次页面路由跳转的时候进行判断,如果是跳转到登陆界面就直接放行
next()
}else{
let token = sessionStorage.getItem('Authorization')
if(token === "null" || token === ''){ //如果是跳转到其他页面,先判断token是否为空或者是否存在,不存在就跳转到登陆界面重新登陆
next('/')
}
else{ //如果有token直接放行
next()
}
}
});
我们来看效果:
在地址栏中修改地址跳过登录页面发现已经无法像上次那样直接跳转,说明拦截验证成功,输入用户名和密码自此登陆成功!
综合[Vue二]:实现页面登录功能,element-ui,vue-router,axios的学习和[vue三]:用户登录状态保存和请求进行判断,vuex结合vue-router,axios的学习,实现了用户登录得完成功能其中涉及以下知识点:element-ui、vue-router、axios、Vuex基本使用,其中加粗内容为重点知识,通过具体实例,对用户登录请求和数据请求安全性有了深入的了解。
欢迎大家关注本人的微信公众号,微信公众号将不定期发送相应学习文章和教程