小程序安全指南之如何禁止外部直接跳转到小程序某页面

 更新时间:2022年09月03日 09:32:41   作者:HullQin  
由于小程序跳转的对象比较多,各自的规则又不一样,因此小程序跳转外部链接是用户咨询较多的问题之一,下面这篇文章主要给大家介绍了关于小程序安全指南之如何禁止外部直接跳转到小程序某页面的相关资料,需要的朋友可以参考下

背景

小程序也需要注意安全性。例如某些页面是业务流程中的「第二步」、「第三步」,而非「第一步」。如果外部小程序、外部二维码、链接直接跳转到了我们小程序的「第二步」、「第三步」,可能有超出预期的事情发生。

针对外部跳转到小程序「第二步」、「第三步」页面的,我们应该拦截掉,要么直接报错:页面来源非法,要么直接跳回首页。

关键问题在于,这种逻辑该怎么实现最优雅呢?

一种不是很好的解决方案

如果你的业务流程采用了状态机模型,并在后端存储了状态,那么可以在每一个页面onLoad时,发送一个API请求,判断当前状态和当前页面是否匹配,如果匹配,则正常访问,如果不匹配,则跳回到状态对应的页面。

这依赖于后端实现,不太合适。

更好的解决方案

我们考虑纯前端的实现。

问题关键在于:我们要禁止外部直接跳转到我们小程序的部分页面。我们需要要区分:内部跳转、外部跳转。

这部分页面,只允许通过内部跳转API(wx.redirectTowx.navigateTo)来跳转,其它方式都不应跳转到。

只要我们在调用wx.redirectTowx.navigateTo时,都加上一个特殊参数。然后在页面的onLoad里面判断,是否包含了该特殊参数,包含该特殊参数,表明是内部跳转,不包含该特殊参数,表明是外部跳转。

这个特殊参数不可以被猜到,如果被猜到了,那么外部跳转时带上特殊参数,该方案就失效了。

所以,这个特殊参数必须不是固定的,要是随机的。

我们可以参考WEB中针对CSRF的解决方案,如果使用随机的特殊参数,让外部无法猜到这个特殊参数,那么问题就解决了。

特殊参数什么时候生成呢?可以在App onLaunch时生成,也可以在「第一步」页面onLoad时生成。不过不论怎样,这个特殊参数都需要作为全局变量保存在内存中,方便随时引用和判断。

具体怎么做?建议你先阅读下文章:《如何全局重写小程序 Page函数 wx对象?》,学会这种方法,我们再来看下方的代码。

全局改写Page的onLoad生命周期,增加校验

const WHITE_LIST = ['pages/index'];

function onLoadProxy(onLoad) {
  return function (query) {
    const app = getApp();
    // 以下是token拦截逻辑:
    if (WHITE_LIST.includes(this.route)) {
      // 在允许外部跳转来的白名单页面,生成随机数validEntranceToken
      app.validEntranceToken = `${new Date().getTime()}${Math.random().toString(36)}`;
    } else if (query.validEntranceToken !== app.validEntranceToken) {
      // 其它页面,校验参数token是否与全局变量中token一致,若不一致,跳转到报错页面
      wx.redirectTo({ url: `/pages/fail` });
      return;
    }
    // 未被拦截,表明是正常来源。以下是正常流程:
    if (onLoad) {
      return onLoad.call(this, query);
    }
  };
}

const PageProxy = (Page) => function (options) {
  const newOptions = {
    ...options,
    onLoad: onLoadProxy(options.onLoad),
  };
  Page(newOptions);
};

Page = PageProxy(Page);

全局改写wx.navigateTo方法,附带参数

function addValidEntranceToken(url) {
  const app = getApp();
  const symbol = url.includes('?') ? '&' : '?';
  return `${url}${symbol}validEntranceToken=${app.validEntranceToken}`;
}

export function redirectToProxy(redirectTo) {
  return function (object) {
    return redirectTo({
      ...object,
      url: addValidEntranceToken(object.url),
    });
  };
}

function wxProxy(wx) {
  const newWx = { ...wx };
  newWx.navigateTo = redirectToProxy(wx.navigateTo);
  newWx.redirectTo = redirectToProxy(wx.redirectTo);
  return newWx;
}

wx = wxProxy(wx);

解释

我们通过修改所有Page的onLoad方法,当用户访问「白名单」页面时,不会做任何拦截,而是直接生成一个随机的validEntranceToken。当用户访问「白名单」以外的页面时,则会判断参数中是否包含正确的validEntranceToken,若不包含,则会跳转到报错页。若包含,则继续执行该页面的其它逻辑。

此外,我们还修改了原生的wx.navigateTowx.redirectTo,当我们做内部跳转时,会自动带上刚才提到的参数validEntranceToken

做好这些事情后,开发时,无需关心细节(意思是这套逻辑针对业务代码是0侵入的),只需要关注「白名单」页面有哪些即可。可谓是最优雅的方案了。

总结

到此这篇关于小程序安全指南之如何禁止外部直接跳转到小程序某页面的文章就介绍到这了,更多相关小程序禁止外部直接跳转某页面内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • UniApp使用manifest.json应用配置的超详细教学

    UniApp使用manifest.json应用配置的超详细教学

    这篇文章主要给大家介绍了关于uni-app应用配置manifest.json最全最详细配置,manifest.json文件是应用的配置文件,用于指定应用的名称、图标、权限等,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • JavaScript引用类型和基本类型详解

    JavaScript引用类型和基本类型详解

    这篇文章主要介绍了JavaScript引用类型和基本类型详解的相关资料,需要的朋友可以参考下
    2016-01-01
  • JS、jQuery中select的用法详解

    JS、jQuery中select的用法详解

    这篇文章主要介绍了JS、jQuery中select的用法详解的相关资料,需要的朋友可以参考下
    2016-04-04
  • JavaScript的词法结构精华篇

    JavaScript的词法结构精华篇

    今天小编就为大家分享一篇关于JavaScript的词法结构精华篇,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • JavaScript30 一个月纯 JS 挑战中文指南(英文全集)

    JavaScript30 一个月纯 JS 挑战中文指南(英文全集)

    JavaScirpt30 是 Wes Bos 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用
    2017-07-07
  • JavaScript实现256色转灰度图

    JavaScript实现256色转灰度图

    本文主要介绍了JavaScript实现256色转灰度图的示例代码,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • 微信小程序实现页面下拉刷新和上拉加载功能详解

    微信小程序实现页面下拉刷新和上拉加载功能详解

    这篇文章主要介绍了微信小程序实现页面下拉刷新和上拉加载功能,结合实例形式分析了微信小程序页面下拉刷新和上拉加载相关事件监听与功能实现操作技巧,需要的朋友可以参考下
    2018-12-12
  • 基于js中的原型、继承的一些想法

    基于js中的原型、继承的一些想法

    下面小编就为大家带来一篇基于js中的原型、继承的一些想法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • JavaScript中if嵌套assert的方法详解

    JavaScript中if嵌套assert的方法详解

    在JavaScript中,通常我们不会直接使用`assert`这个词,因为JavaScript标准库中并没有直接提供`assert`函数,下面是一个详细的示例,展示如何在JavaScript中模拟`assert`函数,并在`if`语句中嵌套使用它来检查条件,需要的朋友可以参考下
    2024-09-09
  • webpack多入口多出口的实现方法

    webpack多入口多出口的实现方法

    这篇文章主要介绍了webpack多入口多出口的实现方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08

最新评论