如何使用FETCH API使用JWT身份验证对WP REST API进行身份验证

时间:2019-04-07 作者:David Gaskin

我的目标是将带有POST请求的用户评论从服务器端Lambda函数发送到我的WordPress API。我正在使用GatsbyNetlify.

当有人在我的盖茨比前端留言时,Netlify会收到form submission event 和aNetlify Lambda function 被调用。正是在这个功能中,我将通过WP-REST API.

问题是我的功能似乎在默默地失败。部分原因可能是Netlify如何提供其功能日志。我的直觉是,需要某种形式的身份验证才能向WP REST API发表评论,所以我继续安装了JWT Authentication Plugin (主要是因为我相信基本身份验证更安全,尽管我不确定)。

我浏览了JWT插件的文档,并对我的.htaccess 还有我的wp-config.php 文件,包括启用CORS支持和定义新密钥:

define(\'JWT_AUTH_SECRET_KEY\', \'your-top-secret-key\');

在Lambda函数中,我对end JWT端点发出post请求:

fetch(\'https://example.com/wp-json/jwt-auth/v1/token\', {
     // credentials: \'include\',
     headers: new Headers({
        \'Authenticate\': \'Basic {what do I put here?}\' // Do I need "Basic"?
     })
  })
  .then(response => {
     console.log("Did we get a response? ", response)
     return response.json()
  })
  .then(myJson => {
     console.log(JSON.stringify(myJson))
  })
  .catch(error => {
     console.log("error: ", error);
     throw new Error(\'Something bad happened.\', error)
  })
我的困惑在于如何正确设置身份验证调用,是否需要进行身份验证,以及是否应该发送WordPressusername:password 或者我在wp-config.php.

用户名/密码的格式应该是什么?是否应进行URL编码,即:username=admin&password=Str0ngPass 或者只是“用户名:密码”。

This question 似乎提供了一种有效的方法,但我没有使用邮递员,甚至无法从我的取回呼叫中获得令牌。我发现还有几个答案更具理论性,在代码示例方面没有提供太多内容:

1 个回复
SO网友:Sally CJ
\'Authenticate\': \'Basic {what do I put here?}\' // Do I need "Basic"?

No, it\'s not Basic. It\'s Bearer. And the header is Authorization.

So first, obtain a token from /wp-json/jwt-auth/v1/token:

fetch( \'http://example.com/wp-json/jwt-auth/v1/token\', {
    method: \'POST\',
    body: JSON.stringify( {
        // Username of a user on the WordPress website in which the REST API request
        // is being made to.
        username: \'user\',
        // And the above user\'s password.
        password: \'pass\'
    } ),
    headers: {
        \'Content-Type\': \'application/json\'
    }
} )
.then( res => res.json() )
.then( res => console.log( res.token ) );

At this point: .then( res => console.log( res.token ) ), you can cache the token, for example in the browser cookies (document.cookie). I mean, if there were no errors (returned by the REST API endpoint), then the token is stored in res.token.

After you obtained a valid token, you can then use the token when making a request to a REST API endpoint such as "Create a Comment" — set the Authorization header and set its value to: Bearer <token>, where in the above example, <token> is the value of the res.token.

fetch( \'http://example.com/wp-json/wp/v2/comments\', {
    method: \'POST\',
    body: JSON.stringify( {
        author_email: \'[email protected]\',
        author_name: \'Test via REST API\',
        content: \'Test comment\',
        post: 123
    } ),
    headers: {
        \'Content-Type\': \'application/json\',
        Authorization: \'Bearer <token>\'
    }
} )
.then( res => res.json() )
.then( res => console.log( res ) );

Make sure the Authorization header is enabled

Because that header is required by the plugin.

And in my case, the Authorization header (which in PHP can be accessed via $_SERVER[\'HTTP_AUTHORIZATION\']) was missing/disabled, so I had to add this to the Apache\'s configuration file (httpd.conf): (requires restarting the Apache server)

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

I did try to add this to the (root) .htaccess file, but it didn\'t work for me:

RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

I hope that helps you and/or someone else having problems with the Authorization header. :)

Resources