尝试使用 Oauth 1.0 在 Wordpress API 中创建帖子时出现 401

Mat*_*iak 2 wordpress post oauth request axios

我正在尝试通过 Wordpress API v2 创建一个 Wordpress 帖子,但是当我执行 axios.post 时,oauth 1.0 向我抛出 401。当我执行 axios.get 时,一切都很完美,我得到了结果。

我可以毫无问题地通过 Postman 创建或删除帖子,但它会自动配置自己。如果我能以某种方式从邮递员那里复制请求并将其放入 axios 代码中,那就太好了,但找不到此选项。

我尝试将内容类型的标头指定为 application/json,如下所示:

headers: {
    'Content-Type': 'application/json'
}
Run Code Online (Sandbox Code Playgroud)

就像在 Postman 中一样,但仍然没有变化。

我正在使用 Oauth 签名生成器,并且正如所指出的那样,它正在 GET 请求中工作。https://www.npmjs.com/package/oauth-signature

这是获取和发布请求的代码:

getRequest = () => {
    const requestParams = { ...this.state.parameters }
    requestParams.oauth_nonce = this.generateNonce()
    requestParams.oauth_timestamp = new Date()
      .getTime()
      .toString()
      .slice(0,10)
    const encodedSignature = oauthSignature.generate(
      'GET',
      'http://localhost/wordpress-api/wp-json/wp/v2/posts/29',
      requestParams,
      this.state.consumerSecret,
      this.state.tokenSecret
    )

    axios({
      url: 'http://localhost/wordpress-api/wp-json/wp/v2/posts/29',
      method: 'get',
      auth: `
        OAuth oauth_consumer_key="${requestParams.oauth_consumer_key}",
        oauth_token="${requestParams.oauth_token}",
        oauth_signature_method="${requestParams.oauth_signature_method}",
        oauth_timestamp="${requestParams.oauth_timestamp}",
        oauth_nonce="${requestParams.oauth_nonce}",
        oauth_version="${requestParams.oauth_version}",
        oauth_signature="${encodedSignature}"
      `
    })
      .then(res => {
        this.setState({
          requestResponse: res
        })
      })
  }

postRequest = (e) => {
    e.preventDefault()

    const postData = {
      title: this.refs.title.value,
      status: 'publish',
      content: this.refs.content.value,
    }

    const requestParams = { ...this.state.parameters }
    requestParams.oauth_nonce = this.generateNonce()
    requestParams.oauth_timestamp = new Date()
      .getTime()
      .toString()
      .slice(0,10)
    const encodedSignature = oauthSignature.generate(
      'POST',
      'http://localhost/wordpress-api/wp-json/wp/v2/posts',
      requestParams,
      this.state.consumerSecret,
      this.state.tokenSecret
    )

    axios({
      url: 'http://localhost/wordpress-api/wp-json/wp/v2/posts',
      method: 'post',
      data: postData,
      auth: `
        OAuth oauth_consumer_key="${requestParams.oauth_consumer_key}",
        oauth_token="${requestParams.oauth_token}",
        oauth_signature_method="${requestParams.oauth_signature_method}",
        oauth_timestamp="${requestParams.oauth_timestamp}",
        oauth_nonce="${requestParams.oauth_nonce}",
        oauth_version="${requestParams.oauth_version}",
        oauth_signature="${encodedSignature}"
      `
    })
      .then(res => {
        this.setState({
          requestResponse: res
        })
      })
  }
Run Code Online (Sandbox Code Playgroud)

Mat*_*iak 5

最后,我想出了问题所在。如果 Wordpress API 有更多示例,那就太好了。我的授权标头设置不正确。

下面是更新后的代码,应该在对 Wordpress API 的任何 Oauth 1.0 安全请求中使用(GET、POST、PUT、DELETE,只需替换'post'oauthSignature.generate()函数和axios请求中的任何方法)。检查并正常工作。

请记住,这只是一个示例,其中包含组件状态中的所有令牌和机密。您应该将这些存储在后端并仅在提供一些凭据后将它们传递给前端。

我已经上传了整个 React 组件代码,因为我艰难地了解到互联网上有多少小的、无法使用的代码片段,而不是一个完整的解决方案,这让我非常恼火。这对所有想要工作示例的人来说应该更具解释性。

// dependencies
import React, { Component } from 'react'
import axios from 'axios'
import oauthSignature from 'oauth-signature'
// components
import '../Styles/Css/Moderator.css'

class Moderator extends Component {
  constructor() {
    super()
    this.state = {
      requestResponse: null,
      parameters: {
        oauth_consumer_key : 'xxxxxxxxxxxxx', // your consumer_key
        oauth_token : 'xxxxxxxxxxxxxxxxx', // your token
        oauth_signature_method : 'HMAC-SHA1',
        oauth_timestamp : '',
        oauth_nonce : '',
        oauth_version : '1.0'
      },
      consumerSecret: 'xxxxxxxxxxxxxxxxxxxxx', // your consumer_secret
      tokenSecret: 'xxxxxxxxxxxxxxxxxxxxx', // your token_secret
    }
  }

  generateNonce = () => {
    let text = ''
    const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    for (let i = 0; i < 11; i++) {
      text += possible.charAt(Math.floor(Math.random() * possible.length))
    }
    return text
  }

  handleSubmit = (e) => {
    e.preventDefault()

    let postData = {
      title: this.refs.title.value,
      status: 'publish',
      content: this.refs.content.value,
    }

    const requestParams = { ...this.state.parameters }
    requestParams.oauth_nonce = this.generateNonce() // unique identifier
    requestParams.oauth_timestamp = new Date()
      .getTime()
      .toString()
      .slice(0,10) // we need just the first 10 digits from current time
    const encodedSignature = oauthSignature.generate(
      'POST',
      'http://localhost/wordpress-api/wp-json/wp/v2/posts',
      requestParams,
      this.state.consumerSecret,
      this.state.tokenSecret
    )

    const authorizationHeader = 
          'OAuth oauth_consumer_key="' + requestParams.oauth_consumer_key
          + '",oauth_token="' + requestParams.oauth_token
          + '",oauth_signature_method="' + requestParams.oauth_signature_method
          + '",oauth_timestamp="' + requestParams.oauth_timestamp
          + '",oauth_nonce="' + requestParams.oauth_nonce
          + '",oauth_version="' + requestParams.oauth_version
          + '",oauth_signature="' + encodedSignature +'"'

    axios({
      method: 'post',
      url: 'http://localhost/wordpress-api/wp-json/wp/v2/posts',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': authorizationHeader
      },
      data: postData
    })
      .then(res => {
        console.log(res)
      })
  }

  render() {
    return (
      <div className='moderator'>
        <form onSubmit={this.handleSubmit}>
          <label>
            Title
            <input type='text' ref='title' />
          </label><br />
          <label>
            Content
            <textarea ref='content' />
          </label>
          <input type='submit' value='Submit' />
        </form>
      </div>
    )
  }
}

export default Moderator
Run Code Online (Sandbox Code Playgroud)