使用JS/React的WooCommerce OAuth 1.0+JWT身份验证

时间:2019-07-18 作者:nnolde

我的方案:

用于用户查询的JWT身份验证,需要自定义.htaccess 要识别Bearer 用于系统查询的授权标头OAuth 1.0a,由于.htaccess 自定义身份验证参数需要进入body/查询字符串中,我使用React作为前端,WP/WooCommerce作为后端。我使用axios (我希望避免将其替换为较低级别的替代品)对于OAuth 1.0,我使用oauth-1.0a.

现在,当oauth参数位于querystring中时,GET请求可以正常工作,但我无法让POST正常工作in JS 这让我抓狂。。然而,当auth参数进入POST正文时,它确实在Postman中起作用,所以我知道这不是服务器问题。我不知道这里什么不起作用。Oauth不是最适合调试的。

下面是一个完全有效的例子,如果有人愿意看看这个的话。我甚至投了一个临时的consumer_keyconsumer_secret 具有read/write 特权。现在这是纯开发人员在WooCommerce中的示例,目前无法破坏太多。不过我很快就会禁用代币。

import axios from \'axios\'
import OAuth from \'oauth-1.0a\'
import crypto from \'crypto-browserify\'

const woocommerce = WooCommerceAPI(\'ck_1da6169c0338088f3e02097a6c9017e800c58176\', \'cs_0e090b0a578f48aa8d1096bcd5525415a856836e\')
woocommerce
  .post(
    \'/customers\',
    {username: \'test\', \'password\': \'test\', email: \'[email protected]\'}
  ).then((response) => {
    console.log(response)
  }).catch( (error) => {
    console.log(error)
  })

class WooCommerceAPI {
  constructor(consumerKey, consumerSecret, timeout = 60000) {
    this.consumerKey = consumerKey
    this.consumerSecret = consumerSecret
    this.timeout = timeout

    this._request = axios.create({
      baseURL: \'https://boundlessmaps.gis-ops.com\' + \'/wp-json/wc/v3\',
      timeout: this.timeout
    })
  }

  _getOAuth() {
    const data = {
      consumer: {
        key: this.consumerKey,
        secret: this.consumerSecret
      },
      signature_method: \'HMAC-SHA1\',
      hash_function: (base_string, key) => {
        return crypto
          .createHmac(\'sha1\', key)
          .update(base_string)
          .digest(\'base64\')
      }
    }

    return new OAuth(data)
  }

  // POST responds with \'Sorry, you are not allowed to create resources.\'

  post(endpoint, data_params, params = null) {
    const method = \'POST\'

    const oauth_params = this._getOAuth().authorize({
      url: \'https://boundlessmaps.gis-ops.com\' + \'/wp-json/wc/v3\' + endpoint,
      method: method,
      data: data_params
    })

    return this._request.post(endpoint, oauth_params)
  }

  // GET requests work

  static _normalizeQueryString(params) {
    if (!params) {
      return \'\'
    }

    let queryString = \'\'
    const params_list = []

    for (const p in params) {
      params_list.push(p)
    }
    params_list.sort()

    for (const i in params_list) {
      if (queryString.length) {
        queryString += \'&\'
      }

      queryString += encodeURIComponent(params_list[i])
        .replace(\'%5B\', \'[\')
        .replace(\'%5D\', \']\')
      queryString += \'=\'
      queryString += encodeURIComponent(params[params_list[i]])
    }

    return \'?\' + queryString
  }

  get(endpoint, params = null) {
    const method = \'GET\'
    const queryString = WooCommerceAPI._normalizeQueryString(params)

    this._request.interceptors.request.use(config => {
      console.log(queryString)
      return config
    })

    const oauth_params = this._getOAuth().authorize({
      url:
        \'https://boundlessmaps.gis-ops.com\' +
        \'/wp-json/wc/v3\' +
        endpoint +
        queryString,
      method: method
    })

    return this._request.get(endpoint, {
      params: { ...params, ...oauth_params }
    })
  }
}

1 个回复
最合适的回答,由SO网友:nnolde 整理而成

Puuh,经过一整天的研究,我意识到了这个问题。。

首先,上面的代码实际上不应该工作。这个oauth 显然,参数必须进入查询字符串。所有WooCommerce客户端API都是这样做的:

post(endpoint, data_params, params = null) {
  const method = \'POST\'

  const oauth_params = this._getOAuth().authorize({
    url: \'https://boundlessmaps.gis-ops.com\' + \'/wp-json/wc/v3\' + endpoint + WooCommerceAPI._normalizeQueryString(params),
    method: method
  })

  return this._request.post(endpoint, data_params, {
    params: oauth_params
  })
}
所以这在理论上应该是可行的,but still doesn\'t. 选项飞行前失败。现在这显然确实是一个服务器端问题。Basically WooCommerce has a limitation 我没有完全理解tbh。解决方法是避免飞行前,如果你避免Content-Type: application/json 标题和abody. 使用axios, 您只需将所有参数放入查询字符串中,并将bodyheaders 空的这并不适用于所有服务器,但幸运的是,它适用于WooCommerce。

参考文献:

相关推荐

OAuth签名不匹配

我在wordpress中使用以下内容来开发基于oauth的应用程序。WP-API (api生成插件)WP API OAuth1 (oauth服务器)和WP API client-cli (oauth客户端库)下面的url用于wp客户端clihttps://man-sudarshann-1.c9.io/api/我收到了这个错误OAuth signature does not match 当我单击AUTH按钮来验证请求时。我已经在互联网上尝试了所有的修复方法。但没有任何帮助api客户端生成和发送的签名为3ko