关于触发登录流程的讨论

项目使用jwt token的验证机制,请求带上token即为登录状态。
但是比较纠结的是,应该通过什么动作去触发登录拿token的这个行为:

  1. 进入第一个页面后,立刻判断token是否有效,无效便触发登录
  2. 不一定一进去就判断token,等到用户主动登录,如果没有主动登录的,接口返回401后触发登录。

第一种情况比较简单,但有的需求的确不能够一开始就登录(比如商城,很多人一开始只是想进去看看商品,并不想注册登录),所有要解决第二种情况,也是我比较困扰的情况。

第二种情况会存在的问题,401触发登录后应该怎么处理原请求。在web端可以通过刷新页面,重新触发原请求,但在小程序端,是没有页面刷新这一说的,所以需要401并且登录完成拿到token后,重新请求数据返回给原接口
(可能封装的不好,请指教~~)

export default function http({
     url,
     method = 'get',
     data = {},
     success = () => {},
     fail = () => {},
     error = () => {}
 }) {
     return new Promise((resolve, reject) => {
         fly.request(url, data, {
             method
         }).then(async res => {
             if (res.code == 1) {
                 return resolve(await success(res))
             }
             return reject(await fail(res))
         }).catch(async err => {
             console.log(err)
             switch (err.status) {
                 case 401:
                     await xcxLogIn()
                     await http({
                         url,
                         method,
                         data,
                         success,
                         fail,
                         error
                     })
                     return resolve()
                     break
                 default:

             }
             return reject(await error(err))
         })
     })
 }

但这样又会出现其他的一些问题。
比如我进到一个页面后,需要一个userInfo和一个收获地址shippingAddressList,因为这些数据我是放在vuex进行托管的,并且初始化为null,所以我得先去判断这两个是不是为null,如果是的话去请求接口,401的话触发登录,然后返回数据,但是这样每个我需要userInfo和shippingAddressList的地方,都得先做判断,太不优雅了,而且,如果未登录情况下,userInfo和shippingAddressList的接口同时请求,就会重复登录,因为没有办法在登录的时候锁住其他请求。

可能描述有点乱。。。
想问问大家对于登录的解决办法~~

阅读 1.2k
1 个回答

刚好前一段时间写过一个商城,先说说我的做法,页面一打开就先发一条初始化请求把缓存在本地的jwt token传到后台进行登录验证【注意是等这个验证收到回调后才执行new Vue】。
验证成功把客户信息缓存到vuex,记录typesuccess
验证失败生成本地临时客户信息缓存到vuex,记录typetemp

为每个route按自定义mete规范配置
下面是我自定的规范

/**
 * 路由meta规范
 meta: {
    keepAlive: false,  //路由是否长活
    transition: true,  //路由是否启用切换动画
    limit: false,      //路由是否登录可见[含临时客户] 默认是  需要设置为false才关闭
    login: true,       //路由是否登录可见[非临时客户] 默认否  需要设置为true才启用
    index: 0           //路由页面顺序 关系到切换动画的左右顺序
    }
*/

然后根据这个规范为vue-router加上beforeEach

import store from '@/store';
import {Toast} from 'vant';

/**
 * 全局路由守卫导航
 * 实现未登录成员除了登录页禁止访问其他页面
 * 待实现后台页面访问记录
 */
export default (router) => {
  router.beforeEach((to, from, next) => {
    //如果当前访问页面不是无限制页面 并且当前成员没有登录 跳到登录页
    if (to.meta.limit !== false && !store.state.appUser.user_id) {
      //记录当前访问页面 使登录或注册成功后可以正确跳回
      store.state.app.route = to.path;
      next({path: '/login'});
    }
    //如果当前访问页面是必须登录页面 并且当前用户是临时用户 跳到登录页
    else if (to.meta.login === true && store.state.appUser.type !== 'success') {
      Toast('请您先登录~');
      //记录当前页面 使登录或注册成功后可以正确跳回
      store.state.app.route = from.path;
      next({path: '/login'});
    } else {
      //判断是否禁止跳转【暂时有订单提交中禁止跳转】
      if (!store.state.app.routeStopJump) {
        if (to.meta.title) {
          document.title = to.meta.title;
        } else {
          document.title = store.state.app.name;
        }
        next();
      } else {
        next(false);
      }
    }
  });
}

这样只要简单配置路由的mete,就很容易实现哪些页面必须要登录才能看,哪些是临时用户游客也能访问了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题