小程序登录状态判断方案?

如何实现用户进入小程序每个页面时候,全局判断其是否登录,如果未登录重定向到登录页,如果登录了就继续后续逻辑。

目前最笨的办法是每个页面都写一个判断方法,缺点就是维护太复杂了,随着页面的增加,这个判断会越来越臃肿和难以维护。

同时也尝试过在app.jsonLaunch方法当中写,但是会遇到有时候网络卡顿等原因,导致第一次登录写入失败,后续用户继续切换页面,就不会再触检查,导致数据出错。

不知道有没有其他更好的方案,能够更简洁优雅的一次验证,全局生效。

阅读 3.2k
6 个回答

最好的办法是交给后端判断, 在封窗的接口处加一个响应拦截如果后端返回这个人已经登录就正常否则就弹窗提示重新登录并重定向登录页

在加个全局的路由监听, 只要用户进入页面就判断, 切换页面时页一定会判断是否登录, 这样就可以了

总之不需要每个页面都写

推荐用这个库 spa-custom-hooks 很好用,我的几个项目都在用。
完美解决 onLaunch 和 onLoad 异步问题,从而就很方便判断是否登陆。
image.png
image.png

1.参考方案:自定义实现路由跳转前拦截

方案1:
/**
 * app.js
 * 在全局变量中新增useCustomRouter方法
*/
// app.js
App({
  globalData: {
    useCustomRouter(type, options) {
      // 处理逻辑
      const isLogin = false;
      if (!isLogin) {
        this.router.redirectTo({
          url: "/pages/login/index"
        });
        return;
      }
      // 基础库 2.16.1 开始支持
      this.router[type](options);
      // 低版本兼容
      wx[type](options);
    }
  },
})

// index.wxml
<view>
    <button bindtap="useRouter">点击</button>
<view>

// index.js

const app = getApp();
const { useCustomRouter } = app.globalData;

Page({
  data: {},
  useRouter() {
    useCustomRouter("navigateTo", {
      url: "/pages/logs/logs"
    });
  }
})

// 方案2:简单粗暴(未经过上传代码测试)
App({
  // 在onLauch钩子直接在wx上挂载
  onLaunch() {
    wx.useCustomRouter = (type, options) => {
      // 处理逻辑
      const isLogin = false;
      if (!isLogin) {
        this.router.redirectTo({
          url: "/pages/login/index"
        });
        return;
      }
      // 基础库 2.16.1 开始支持
      this.router[type](options);
      // 低版本兼容
      wx[type](options);
  }
})

// index.js
Page({
  useRouter() {
    wx.useCustomRouter("navigateTo", {
      url: "/pages/logs/logs"
    });
  },
})

2.使用@玛拉_以琳提出的通过接口验证,401跳转至登录页

1, 你应该在onlaunch 发送一个预判断请求checkToken,并showLogin
2, 你应该在封装HTTP服务,它在遇到没有token或者后端返回token错误时拦截请求跳转到登录页;判断当heckToken请求正在发送时拦截业务请求,在heckToken请求正在发送时结束时继续发送。

// 封装请求方法
function sendData(resConfig) {
  const config = assign(extendEasy({}, defaultConfig), resConfig)
if (config.showLoading) {
    showRequestLoading()
  }
// 判断是否有登录请求正在进行
  if(store.data.loginStatus || !store.data.token) {
    store.data.waitList.push({
      data, resolve, reject, complete
    })
  }

wx.request({
...
})

}

// 封装登录
export function login(data) {
  store.setData('loginStatus', true);
  const config = {
    data, 
    resolve: (resp) => {
      store.setData('token', resp.token);
      sendWaitList(sendData, store.data.waitList);
      store.data.waitList = []
    },
    reject: () => {
      store.setData('token', null);
    },
    complete: () => {
      store.setData('loginStatus', false);
    }
  }
  sendData(config)
}

// 处理waitList
export function sendWaitList(send, list){
  list.forEach(config => {
    sendData(config)
  });
}
新手上路,请多包涵

能不能在这个Page({})这里面的这个对象上想方法

let obj = {

onShow: function() {}

}
Page(obj)

把这个onShow搞成公共的

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