首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WooCommerce OAuth 1.0 + JWT的JS/React认证

WooCommerce OAuth 1.0 + JWT的JS/React认证
EN

WordPress Development用户
提问于 2019-07-18 09:31:11
回答 1查看 1.5K关注 0票数 0

我的场景:

  • 用于用户查询的JWT,这需要自定义.htaccess来识别Bearer授权头
  • OAuth 1.0a用于系统查询,并且由于.htaccess自定义,因此auth参数需要进入主体/查询字符串

我使用React作为前端,WP/WooCommerce作为后端。我使用axios (我希望避免将它替换为低级的替代品),对于OAuth 1.0,我使用oauth-1.0a

现在,当oauth参数在查询字符串中时,GET请求工作得很好,但我只是无法在JS中得到POST,它让我发疯了。但是,在Postman中,当auth参数进入POST主体时,它确实有效,所以我知道这不是服务器问题。我一点也不知道什么不管用。Oauth并不是最适合调试的。

下面是一个充分发挥作用的例子,如果有人想看看这个。我甚至还提供了一个临时的consumer_keyconsumer_secret,并提供了read/write特权。它现在是纯开发的,在WooCommerce中有样的东西,在这一点上不能破坏太多。不过,我很快就会禁用这些代币。

代码语言:javascript
复制
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: 'test@bullocks.com'}
  ).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 }
    })
  }
}
EN

回答 1

WordPress Development用户

回答已采纳

发布于 2019-07-18 11:55:20

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

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

代码语言:javascript
复制
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
  })
}

所以理论上这应该是可行的,但还是不行。试飞前的选择失败了。这显然是一个服务器端的问题。基本上,WooCommerce有一个限制,我没有完全理解它。方法是避免预飞行,这显然是可能的,如果您避免Content-Type: application/json头和body。使用axios,只需将所有参数放入查询字符串,并将bodyheaders保持为空。这并不能在所有服务器上工作,但幸运的是,它适用于WooCommerce。

参考文献:

工作解决办法是:

代码语言:javascript
复制
post(endpoint, data_params) {
  const method = 'POST'

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

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

(愉快的黑客活动;)

票数 1
EN
页面原文内容由WordPress Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://wordpress.stackexchange.com/questions/343139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档