vue 前端登录拦截

       在用vue开发过程中,经常会遇到这种需求,有些组件是需要登录之后才能够去访问,有些组件是任何用户都能够访问,我们可以通过前端路由拦截+http拦截来达成这种目的(假定以token来验证)。

技术栈:

  • vue2.0
  • vue-router
  • axios

目录结构:

前端路由拦截

    路由配置如下,在这里自定义了一个元数据meta: {authRequired: true}来标记哪些路由是需要登录验证的,导航被触发的时候只要判断是否目标路由中是否有meta这个对象,且meta包含authRequired属性,其值为true。这里访问/user/userinfo是需要登录拦截的。

const router = new Router({
  routes: [
    {
        path: '/',
        redirect: '/homepage',
    },
    {
        path: '/login',
        component: LogIn
    },
    {
        path: '/homepage',
        component: HomePage,
        children: [
            {
                path: 'userinfo',
                component: UserInfo,
                meta: {authRequired: true}
            },
            {
                path: 'news',
                component: News,
            }
        ]
    }
  ]
})


通过router.beforeEach注册一个全局前置守卫来进行判断拦截,每一次导航被触发时都会调用这个全局守卫。

router.beforeEach((to, from, next) => {
    //判断是否需要登录拦截
    if(to.meta.authRequired) {
        //存在token正常跳转
        if(localStorage.getItem('token')) {
            next()
        } else {
            next({path: '/login', query:{redirect: to.fullPath}})
        }
    } else {
        next()
    }
})
next({path: '/login', query:{redirect: to.fullPath}})
//在触发/login路由时,会携带额外的参数,相当于/login?redirect=to.fullPath,目的是在登录完成之后可以返回到当前页面。

对于嵌套路由,做好使用如下代码判断,当你访问一个子路由时,会同时匹配到当前路由和父路由。

请参考https://router.vuejs.org/zh/guide/advanced/meta.html

if(to.matched.some(record => {record.meta.authRequired})) {//....}


http拦截

vue-resource在vue2.0之后已不再维护,推荐使用axios http库。

这里需要对每个request都绑定上token,对每个response都需要验证其状态。

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    config.headers['Authorization'] = localStorage.getItem('token');
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });


// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    return response;
  }, function (error) {
    // 当验证不通过,则清除本地保存的token,并且返回登录界面
    if(error.status === 401) {
        localStorage.removeItem('token');
        this.$router.push('/login');
    }
    return Promise.reject(error);
  });

后端代码

后端:python2.7 + webpy

需要安装webpy和pyjwt。


index.py

# -*- coding:utf-8 -*-

import web
import time
import jwt
import json

url = (
    '/login', 'Login',
    '/userinfo', 'UserInfo'
)

USER = 'admin'
PASSWORD = '123456'

app = web.application(url, globals())


def create_token():
    payload = {
        "iat": int(time.time()),
        "exp": int(time.time()) + 86400 * 7,
        "scopes": ['open']
    }
    token = jwt.encode(payload, 'secret', algorithm='HS256')
    return {'token': token}


def verify_bearer_token(token):
    try:
        payload = jwt.decode(token, 'secret', algorithms=['HS256'])
    except Exception, e:
        print e
        return False
    else:
        if payload:
            return True
        else:
            return False


class Login(object):
    def POST(self):
        data = eval(web.data())
        try:
            if data['usr'] == USER and data['psd'] == PASSWORD:
                token = create_token()
                return json.dumps(token)
        except Exception, e:
            print e
        web.ctx.status = '401'
        return json.dumps({'status': 'fail'})


class UserInfo(object):
    def GET(self):
        if 'HTTP_Authorization'.upper() in web.ctx.env:
            token = web.ctx.env['HTTP_Authorization'.upper()]
            if token and verify_bearer_token(token):
                return json.dumps({'firstname': 'ab', 'lastname': 'cd'})
        web.ctx.status = '401'
        return json.dumps({'status': 'fail'})


if __name__ == '__main__':
    app.run()

运行:

先运行python2.7 index.py 80,然后在vue项目的根目录执行npm run dev,在浏览器输入127.0.0.1:8080即可查看demo。


github地址:https://github.com/shanjianfei/vue_intercept


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值