08月14, 2022

关于 Firekylin 后台设置出现 “REFERRER_ERROR” 的问题解决

后台发布文章时,点击发布文章或保存草稿,页面没有反应。简单抓包,发现Api返回REFERRER_ERROR。

原因

前端的域名和数据库中site_url字段不一致。仅当一致的时候,数据才能正常返回(估计是为了防止其他域名的请求,所以做了源的判断)。

if(action !== 'get') {
      let referrer = this.ctx.referrer();
      let {site_url} = await this.model('options').getOptions()
      if(!referrer || !site_url) {
        return this.fail('REFERRER_ERROR');
      }
      let siteUrlHost = parse(site_url).host;
      let referrerHost = parse(referrer).host;
      if(!siteUrlHost || !referrerHost) {
        return this.fail('REFERRER_ERROR');
      }
      if(siteUrlHost.length < referrerHost.length) {
        if(referrerHost.slice(-siteUrlHost.length) !== siteUrlHost) {
          return this.fail('REFERRER_ERROR');
        }
      } else {
        \\ 错误原因
        if(siteUrlHost.slice(-referrerHost.length) !== referrerHost ) {
          return this.fail('REFERRER_ERROR');
        }
      }
    }

产生问题的原因:我先把代码拉到服务器运行的,Firekylin第一次运行有数据安装的过程,估计当时就写入了site_url。导致后来我本地开发,域名和数据库中site_url不一致。

解决办法

获取think全局对象,通过env字段,判断当前的环境。如果是开发环境,那么就不进行域名和site_url的判断。(也许有很多上层好的控制策略,但是我小菜鸡一枚,嘻嘻嘻)

//env常量
    const env = think.env;
    if(action !== 'get') {
      let referrer = this.ctx.referrer();
      let {site_url} = await this.model('options').getOptions()
      if(!referrer || !site_url) {
        return this.fail('REFERRER_ERROR');
      }
      let siteUrlHost = parse(site_url).host;
      let referrerHost = parse(referrer).host;
      if(!siteUrlHost || !referrerHost) {
        return this.fail('REFERRER_ERROR');
      }
      if(siteUrlHost.length < referrerHost.length) {
        if(referrerHost.slice(-siteUrlHost.length) !== siteUrlHost) {
          return this.fail('REFERRER_ERROR');
        }
      } else {
        // 开发环境siteUrl不进行判断
        if(siteUrlHost.slice(-referrerHost.length) !== referrerHost && env !== 'development') {
          return this.fail('REFERRER_ERROR');
        }
      }
    }

本文链接:https://imyoyo.xyz/post/referrer-error-of-firekylin-admin.html

-- EOF --

Comments