vue项目中用token和localstorage实现登陆

整体流程:

  1. 在登陆页面调用登陆接口拿到token,存到localstorage里面

  2. 用request拦截器拦截所有请求,并把所有的请求都加一个请求头:从localstorage里面拿到的token

  3. 跳转页面之前用路由守卫判断localstorage里面有没有token,如果没有则跳转到登陆页面

  4. 如果调用接口时发生token过期或其他token异常则后端接口返回401状态码,前端用response拦截器拦截请求结果,发现请求的状态码是401则清除localstorage里面的token,之后就会被路由守卫发现没有token,然后自动跳转到登陆页面重新登陆

登陆页面:调用登陆接口拿到token,把token存到logalstorage中

<template>
    <div class="full">
        <div class="block">
            <el-form class="form" ref="form">
                <h3 class="title">个人博客管理系统</h3>
                <el-form-item>
                    <el-input placeholder="请输入邮箱" v-model="form.email"></el-input>
                    <el-input placeholder="请输入密码" type="password" v-model="form.password"></el-input>
                </el-form-item>

                <el-form-item>
                    <el-button class="sub" type="primary" @click="submit">登陆</el-button>
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>

<script>
import {
    bloggerLogin
} from "../api/login.js"

export default {
    name: "Login",

    created () {
        //已登录状态再进入登陆页面,直接跳转到管理首页。不允许登陆状态再次登陆
        let token = localStorage.getItem('Authorization');
        if (token != null || token != '') {
            this.$router.push("index")
        }
    },

    data () {
        return {
            form: {
                email: '',
                password: ''
            }
        };
    },
    methods: {
        submit () {
            let _this = this;
            let params = {
                email: this.form.email,
                password: this.form.password
            }
            console.log(params);
            bloggerLogin(params).then(res => {
                console.log(res);
                localStorage.setItem('Authorization', res.data.Authorization)
                _this.$router.push("index")
            })
        }

    },
};
</script>

request拦截器,从localstorage里面拿到token,并装到请求头里面

service.interceptors.request.use(
        config => {
            config.headers['Authorization'] = localStorage.getItem("Authorization");
            config.headers['Content-Type'] = 'application/json'
            return config
        },
        error => {
            Promise.reject(error)
        }
    )

路由守卫拦截:

router.beforeEach((to, from, next) => {
    if (to.path === '/login') {
        next()
    } else {
        let token = localStorage.getItem('Authorization');
        console.log(token);
        console.log(token == null);
        if (token == null || token == '') {
            next('/login');
        } else {
            next();
        }
    }
})

response 拦截器。重点就一个:状态码是401则清除localstorage里面的token

service.interceptors.response.use(
    response => {
        const code = response.status
        if (code < 200 || code > 300) {
            Notification.error({
                title: response.message
            })
            return Promise.reject('error')
        } else {
            if (response.status === undefined) {
                return response.status
            }
            if (response.data.code === 401) {

                localStorage.removeItem("Authorization");
                // Notification.error({
                //     title: response.data.message
                //   })
            } else if (response.data.code === 403) {

                Notification.error({
                    title: response.data.message
                })
            }
            return response.data
        }
    },
    error => {
        let code = 0
        try {
            code = error.response.data.status
        } catch (e) {
            if (error.toString().indexOf('Error: timeout') !== -1) {
                Notification.error({
                    title: '网络请求超时',
                    duration: 5000
                })
                return Promise.reject(error)
            }
        }
        if (code) {
            if (code === 401) {

                Notification.error({
                    title: '网络请求超时',
                })
            } else if (code === 403) {
                Notification.error({
                    title: '提示403,权限问题',
                })
            } else {
                const errorMsg = error.response.data.message
                if (errorMsg !== undefined) {
                    Notification.error({
                        title: errorMsg,
                        duration: 5000
                    })
                }
            }
        } else {
            Notification.error({
                title: '接口请求失败',
                duration: 5000
            })
        }
        return Promise.reject(error)
    }
)

参考:Vue项目中实现用户登录及token验证

上一篇:html-面试题


下一篇:前端缓存