一直都想尝试一下登录功能的过期时间, 虽然只是一个普普通通的功能,但是还是学到了很多!!因为都是看别人怎么弄啊方法啥的 没有机会自己动手实践,这次和后端同学配合了一下~~开心
- 首先是后端返回了token
- 前端获取到token后,将token扔到axios发送的请求头中,以保证每次发送请求,token都可以在头部随着请求一起发给服务端(即采用请求头携带token的方式)
- 同时扔到window.localStorage里面 进行保存,这样前端可以通过检验localStorage中是否有token进行一系列操作(这里后面会同时尝试将token扔到cooke和sessionStorage)
1. 把token存在window.localStorage
我们是这样定义路由的, 将需要登录权限的设置meta属性
// router/index.js
{
path: '/personal',
name: 'Personal',
meta: {
requireAuth: true
},
component: Personal
}
使用全局前置守卫来拦截导航 to即将要进入的目标路由对象
如果即将进入的目标对象有这个登录权限,即从当前路由进入到个人中心时 需要进行登录
// router/index.js
router.beforeEach((to, from, next) => {
// 我们需要从localStorage下获取这个token
let token = window.localStorage.getItem('token')
if (to.meta.requireAuth) {
// 如果token记录了, 就不用重新登录~
if (token) {
// 直接调用getPong 获取个人信息
store.dispatch('getPong')
next()
} else {
// 如果没有token,意味着要重新登录,所以首先先登出,清除一下state中的状态
store.dispatch('logOut')
next({
path: '/login',
query: {redirect: to.fullPath}
})
}
} else {
next()
}
})
2. 如何抓取token,并放入localStorage中
-
封装方法
// api/index.js import Axios from 'axios' if (window.localStorage.getItem('token')) { // 全局配置下添加token在headers请求头上 Axios.defaults.headers.common['token'] = window.localStorage.getItem('token') } export let instance = Axios.create() // response拦截器 这个拦截器主要时为了当token过期的时候,返回401时作处理 instance.interceptors.response.use( response => { // console.log('拦截器:') // console.log(response) return response }, error => { if (error.response) { if (error.response.success === 0) { console.log('token无效') } } return Promise.reject(error.response) } ) export const login = ({email, password}) => { return instance.post('/apii/api/auth/login', { email: email, password: password }) } export const getPong = () => { return instance.get('/apii/api/pong') }
-
这里通过this.$store.dispatch()分发action
// login.vue <template> <div> <form @submit.prevent = "login"> <el-input v-model="input" placeholder="请输入用户名"></el-input> <el-input v-model="password" placeholder="请输入密码" show-password></el-input> <el-button size="medium" round @click="login">登录</el-button> </form> </div> </template> <script> export default { data () { return { input: '', password: '' } }, methods: { login () { if (this.input === '') { this.$message.warning('用户名不能为空') } else if (this.password === '') { this.$message.warning('密码不能为空') } else { this.$store.dispatch('toLogin', { email: this.input, password: this.password }).then(() => { // 只有header中存在header才可以成功请求 // this.$router.push({path: this.redirect || '/', query: this.otherQuery}) let redirectUrl = decodeURIComponent(this.$route.query.redirect || '/') // console.log('redirectUrl:' + redirectUrl) // 登录成功后自动跳转到个人中心 this.$router.replace(redirectUrl) // 获取个人信息 this.$store.dispatch('getPong') }).catch((err) => { console.log(err) }) } } } } </script>
actions.js下定义这个toLogin方法
toLogin ({commit}, info) { return new Promise((resolve, reject) => { login(info).then((res) => { // resolve(res) if (res.status === 200) { commit(types.LOGIN, res.data.data.token) // 存储token commit(types.LOGINSTATUS, true) // 将token扔到instance的请求头里 instance.defaults.headers.common['token'] = res.data.data.token // 将token设置在localStorage window.localStorage.setItem('token', res.data.data.token) resolve(res) } // console.log(res) }).catch((error) => { reject(error) }) }) }
当我们把token放到localStorage之后,我们可以观察到 headers中有了token 这样服务器端收到请求之后,就开始解析token
如果想要清除token
window.localStorage.removeItem('token')
以上,我们实现了
- 点击个人中心时,受到登录权限限制,跳到登录界面
- 使用正确的账号密码登录后,接收后端返回的token,并且把token存入到localStorage和在axios请求头上进行携带
- 此时,刷新页面后,仍然可以直接进入个人中心页面
- 当然,我们可以通过退出登录来将token删除,此时再进入个人中心页面就需要登入了
这里,token过期是后端判断的,后端判断过期后,你发的请求就会失败,后端可以返回一个特定的状态码如401回来,前端通过拦截器interceptor中处理跳转到登录页面