V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
firhome
V2EX  ›  程序员

有木有前端大神,请教个登录拦截的问题。

  •  
  •   firhome · 2019-11-13 10:04:17 +08:00 · 3373 次点击
    这是一个创建于 1597 天前的主题,其中的信息可能已经有所发展或是发生改变。
    项目用的是 vue + axios

    现在情况是这样。

    list.vue --> 接口所有用户都能看

    detail.vue --> 接口必须登录才能看


    我在 axios 里对页面请求进行了处理。

    如果遇到需要登录的接口,直接跳登录页面 登录后再跳转回来。

    这个流程应该没什么问题。。。。


    但是用户会这么操作 。 list --> detail(请求发现未登录 跳转到登录 login) ----> 用户不想登录操作,想返回 list

    就发现返回不了。 因为路由是 从 detail 到 login, 从 login 只能返回到 detail (发现未登录 又跳 login )


    请问这种情况怎么解决呢?
    第 1 条附言  ·  2019-11-13 11:34:56 +08:00
    谢谢大家回复。

    打算如下更改:

    1. 前端 beforeRouter 的时候判断哪些页面需要登录。

    2. 有 token 并且进页面请求以后发现过期,在 axios 里拦截。

    3. 跳到 login 和 login 之后返回页面都用 router.replace

    基本就解决了。

    谢谢大家
    23 条回复    2019-11-13 16:48:57 +08:00
    wxwxwai
        1
    wxwxwai  
       2019-11-13 10:09:27 +08:00
    不要跳到 detail 里面进行判断,在 beforeRouterEnter 里判断是否登录即可。
    chengxy
        2
    chengxy  
       2019-11-13 10:09:28 +08:00
    在跳转 detail 之前去做拦截操作呗,就是在 list 页再写一遍拦截的方法,其实可以提出来,再跳页面之前都要先执行这个方法。
    iPumpkin
        3
    iPumpkin  
       2019-11-13 10:10:22 +08:00
    在路由进入 detail 之前用 router.beforeEach 拦截
    coolooks
        4
    coolooks  
       2019-11-13 10:10:43 +08:00
    记录 detail 之前的页面链接,用户返回时跳转此链接
    firhome
        5
    firhome  
    OP
       2019-11-13 10:12:16 +08:00
    @wxwxwai
    @iPumpkin

    感谢回复。所有需要登录的接口 都要在 beforeEach 里做吗?
    learnshare
        6
    learnshare  
       2019-11-13 10:15:17 +08:00
    1. 每个路由配置 meta.login = true
    2. router.beforeEach 里检查 login === true && !login 时,重定向到登录页面
    这样开哪页之前都有检查了

    针对你这个场景,注意第二步是“重定向”,返回的时候会回到 list 页面
    iPumpkin
        7
    iPumpkin  
       2019-11-13 10:16:35 +08:00
    先在路由里加一个路由元信息 meta: { requiresAuth: true }

    然后在 router.beforeEach 中统一判断 to.meta.requiresAuth 是否需要提示登录
    Toninie
        8
    Toninie  
       2019-11-13 10:28:26 +08:00   ❤️ 4
    detail 跳登录时别用 push,用 replace,这样后退就直接回 list 了
    zaul
        9
    zaul  
       2019-11-13 10:39:59 +08:00
    别用 push,用 replace
    mlxj
        10
    mlxj  
       2019-11-13 10:44:03 +08:00
    就不能在登录页面弄个返回按钮、
    fancy111
        11
    fancy111  
       2019-11-13 10:47:39 +08:00
    为什么要跳到 detail 再判断登录?不是应该先通过 cookie 或者 token 之类的判断登录状态,再选择跳 login 和 detail 吗?
    整个设计逻辑错误,竟然没人发现
    shengchao
        12
    shengchao  
       2019-11-13 10:54:48 +08:00
    在 detail 页面直接使用 this.$router.replace('url')就可以了,不要使用 push
    fishlium
        13
    fishlium  
       2019-11-13 11:08:13 +08:00
    #6 #7 的方案比较通用
    HowardTang
        14
    HowardTang  
       2019-11-13 11:09:15 +08:00
    路由鈎子
    seniorLemon
        15
    seniorLemon  
       2019-11-13 11:21:19 +08:00
    就我同意#11 观点嘛(狗头)
    123s
        16
    123s  
       2019-11-13 11:30:27 +08:00
    #6 楼那样就行了
    DoveAz
        17
    DoveAz  
       2019-11-13 11:30:30 +08:00
    没登录不让点 detail 链接不就行了,整这么麻烦干啥
    firhome
        18
    firhome  
    OP
       2019-11-13 11:31:45 +08:00
    @fancy111
    @seniorLemon

    因为 token 会过期,之前考虑没这么复杂,偷懒了。

    看了大家的答案,路由上我也再做些拦截吧。

    进了页面过期以后 再跳回 login,再加上 router.replace 就可以解决这个问题了

    谢谢大家。
    oneisall0423
        19
    oneisall0423  
       2019-11-13 11:38:15 +08:00
    个人认为,在 router.beforeEach 里用路由元信息判断比较好。
    yinft
        20
    yinft  
       2019-11-13 11:42:31 +08:00
    肯定没好好看 vue-router
    RookieZoe
        21
    RookieZoe  
       2019-11-13 12:09:54 +08:00
    vue-router 和 axios 拦截器搭配使用
    wangyzj
        22
    wangyzj  
       2019-11-13 12:27:24 +08:00
    router.beforeEach
    ceet
        23
    ceet  
       2019-11-13 16:48:57 +08:00
    // 页面权限
    router.beforeEach((to, from, next) => {
    if(to.matched.some(item => item.meta.requiresAuth)) {
    // 当 token 存在证已经登录,设置登录后的请求头,否则进入登录页面
    if(sessionStorage.token) {
    axios.defaults.headers['Authorization'] = 'bearer ' + sessionStorage.token;
    next();
    } else {
    next({
    path: '/Login'
    });
    }
    } else {
    if(to.path == '/Register' || to.path == '/FindPwd' || to.path == '/Login') {
    axios.defaults.headers['Authorization'] = '';
    }
    next();
    }
    // 响应拦截(配置请求回来的信息)
    axios.interceptors.response.use(function(response) { // 处理响应数据
    // 判断如果请求返回 1004 3301 4004 5501 状态码,即登录超时,清除 token 并跳回登录页
    if(response.data.code == '1004' || response.data.code == '3301' || response.data.code == '5501') {
    vant.Notify({
    message: response.data.msg,
    duration: 1000,
    background: '#1989fa'
    });
    sessionStorage.clear();
    next({
    path: '/Login'
    });
    }
    return response;
    }, function(error) { // 处理响应失败
    setTimeout(() => {
    if(error.response.status == '404') {
    vant.Notify({
    message: '404 请求接口地址错误',
    duration: 1000,
    background: '#1989fa'
    });
    } else if(error.response.status == '405') {
    vant.Notify({
    message: '405 请求类型错误',
    duration: 1000,
    background: '#1989fa'
    });
    } else if(error.response.status == '500') {
    vant.Notify({
    message: error.response.data.msg,
    duration: 1000,
    background: 'rgb(255, 68, 68)'
    });
    } else if(error.response.status == '504') {
    vant.Notify({
    message: '504 网关错误',
    duration: 1000,
    background: 'rgb(255, 68, 68)'
    });
    } else {
    vant.Notify({
    message: error.response.status + ' 其他错误:' + error.response.data.msg,
    duration: 1000,
    background: 'rgb(255, 68, 68)'
    });
    }
    }, 1000);
    return Promise.reject(error);
    });
    });
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1212 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 23:14 · PVG 07:14 · LAX 16:14 · JFK 19:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.