简体   繁体   English

在Wordpress上具有授权标头(CORS)的HTTP发布

[英]HTTP Post with Authorization header (CORS) on Wordpress

I can't achieve to POST something using Authorization: Bearer -token- and I hardly suspect my server configuration. 我无法使用Authorization: Bearer -token-实现某些内容的发布Authorization: Bearer -token- ,几乎不怀疑服务器配置。 I am using MAMP Pro, in a wordpress based server. 我在基于wordpress的服务器中使用MAMP Pro。 That server delivers an API (this is not the Rest API wordpress plugin). 该服务器提供一个API(这不是Rest API wordpress插件)。 This API works fine when i'm using Postman. 当我使用Postman时,此API可以正常工作。

My typical use case is : 我的典型用例是:

  1. Post from https://front-end.com/login.html to https://back-end.com/api/users/auth in POST with username/pwd as parameters. 在POST中以用户名/密码为参数从https://front-end.com/login.html发布到https://back-end.com/api/users/auth
  2. Returns me a JWT token called myToken 返回给我一个名为myToken的JWT令牌
  3. Post from https://front-end.com/index.html to https://back-end.com/api/alert in POST with input1/input2 as parameters and Authorization: Bearer <myToken> as Header. 从POST中的https://front-end.com/index.html发布到https://back-end.com/api/alert ,其中input1 / input2作为参数, Authorization: Bearer <myToken>作为标题。

JS Code for step 1 步骤1的JS代码

const API_ROOT_URL = "https://back-end.com";
const API_AUTH = "api/users/auth";
const API_ALERT = "api/alert";
const METHOD_POST = "POST";

return new Promise((resolve: any, reject: any) => {
let request = new XMLHttpRequest();
            request.open(METHOD_POST, API_ROOT_URL+"/"+API_AUTH);
           // request.setRequestHeader('Content-Type', 'multipart/form-data');
            request.onload = () => resolve(request.response);
            request.onerror = () => reject(request.response);
            request.send(formData);

JS Code for step 3 : 步骤3的JS代码:

        return new Promise((resolve: any, reject: any) => {
        let request = new XMLHttpRequest();
        request.open(METHOD_POST, API_ROOT_URL+"/"+API_ALERT);
        request.setRequestHeader('Authorization', "Bearer  "+ AnotherClass.getJwtToken());
      //  request.setRequestHeader('Content-Type', 'multipart/form-data');
        request.onload = () => resolve(request.status);
        request.onerror = () => reject(request.status);
        request.send(formData);
    });

The step 1 works fine. 步骤1正常运行。 JWT token is retrieved using Postman OR my regular Webapp on front-end.com. 使用Postman或我在front-end.com上的常规Webapp检索JWT令牌。

The step 3 works fine with Postman, where my Form is successfully posted and I received a 200. But when I use it with my WebApp,I cannot pass the preflight OPTION request. 步骤3在Postman上可以正常工作,在Postman上我的表单已成功发布,并且收到200。但是,当我将其与WebApp一起使用时,我无法通过预检OPTION请求。

Note that I also mocked my API using mockable.io (which is https too) and the request successfully pass ; 请注意,我还使用了ockable.io(也是https)来模拟我的API,并且请求成功通过; this is not important in our case but this is why I suspect a wrong server configuration. 这对我们来说并不重要,但这就是为什么我怀疑服务器配置错误。

Tested : 经测试:

A. Rewrite rule in MAMP Virtual Host : A. MAMP虚拟主机中的重写规则:

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

B. Rewrite rule in the htaccess of my wordpress server (same as above, pushed after existing rewrite rules) B.在我的wordpress服务器的htaccess中重写规则(与上述相同,在现有重写规则之后推送)

C. For test purpose, removed "Authorization: Bearer" to see if request goes to POST (and it does with no surprise) C.出于测试目的,删除了“授权:承载”以查看请求是否转到POST(并且毫不奇怪)

D. Tried to add SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 in .htaccess, with and without the previous rewrite rules. D.尝试在.htaccess中添加SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 ,使用和不使用以前的重写规则。

E. As stated in JS code above, tried to hard-set Contet-Type to multipart, with no improvement. E.如上面的JS代码所述,尝试将Contet-Type硬设置为多部分,没有任何改进。

F. Tried to add / in the endpoint API_ALERT just in case wordpress do silly redirection (experienced that before) F.试图在端点API_ALERT中添加/以防万一wordpress做愚蠢的重定向(之前有过经验)

I have now absolutely no idea where to look for. 我现在完全不知道在哪里寻找。 I suspect either an Apache configuration blocking Authorization, or Wordpress messing with Cors or Authorization. 我怀疑Apache配置阻止了授权,或者Wordpress与Cors或授权搞混了。

If this had a subtitle, it would be "Story of JWT Authorization on a custom Wordpress using no plugins, with a JavaScript WebApp on another domain using Service Workers and XHR" 如果有副标题,则将是“不使用插件的自定义Wordpress上的JWT授权故事,在另一个域上使用Service Workers和XHR使用JavaScript WebApp”

Auto-congratulating myself, but special thanks to https://www.html5rocks.com/en/tutorials/cors/ , providing crystal-clear informations about how servers and scripts interact. 自动祝贺自己,但特别要感谢https://www.html5rocks.com/zh-cn/tutorials/cors/ ,它提供了有关服务器和脚本如何交互的清晰信息。

Using Wordpress, my solution was (I changed nothing from my JS code): 使用Wordpress,我的解决方案是(我对JS代码未做任何更改):

  1. Add the following Before the #BEGIN WordPress statement #BEGIN WordPress语句之前添加以下内容

     <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP:Authorization} ^(.*) RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1] </IfModule> 
  2. In your Route service, savagely bypass "addRoute" method by using : 在您的Route服务中,使用以下方法大胆地绕过“ addRoute”方法:

     $this->routes[] = [ltrim("/api/alert", '/'), [$myApiController, 'alertAction']]; 
  3. In the API Controller $myApiControler create the entry point function alertAction 在API控制器$myApiControler创建入口点函数alertAction

     public function alertAction() { $request = Request::getInstance(); if(!$request->isXmlHttpRequest()) { switch($request->getMethod()) { case Request::METHOD_OPTIONS: $this->handleOptionsMethod(); break; case Request::METHOD_POST: $this->handlePostMethod($request); break; default: $response = new Result(404); status_header($result->getCode()); echo $response; die(); break; } } 

    } }

  4. In the handleOptionsMethod() method create the appropriate Options response, with the required headers handleOptionsMethod()方法中,使用所需的标头创建适当的Options响应

     private function handleOptionsMethod() { $response = new Result(200); status_header($response->getCode()); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: POST'); header('Access-Control-Allow-Headers: Authorization'); echo $response; die(); } 
  5. In the handlePostMethod() method, do what you have to. 在handlePostMethod()方法中,执行所需的操作。

     private function handlePostMethod($request) { $requestData = $request->request->all(); $authorization = $request->headers->get('Authorization'); $jwt = str_replace('Bearer ', '', $authorization); $decoded = JWT::decode($jwt, JWT_SECRET_KEY, array('HS256')); $userId = (int) $decoded->data->userId; ... $response = new Result(200) status_header($result->getCode()); echo $response; die(); } 

Yet, basically : - Allow your server to read additionnal HTTP informations - Allow your wordpress instance to do specific stuff on OPTIONS request - Create the response headers your script needs to allow the preflight request (allow "Authorization" custom header in my case) - Create the regular request handler (your post, or get). 但是,基本上来说:-允许您的服务器读取其他HTTP信息-允许您的wordpress实例对OPTIONS请求执行特定的操作-创建脚本以允许预检请求所需的响应标头(在我的情况下允许“ Authorization”自定义标头)-创建常规请求处理程序(您的发布或获取)。

Hope this will help some of you. 希望对您有所帮助。

Last part of my problem is, now that the POST request successfully triggers, the Service Worker does NOT work, and therefore I can't access the "response" and handle it properly. 我的问题的最后一部分是,既然POST请求已成功触发,则Service Worker无法正常工作,因此我无法访问“响应”并正确处理它。 But I already made a big step forward and wanted to share it with some of you. 但是我已经迈出了一大步,并希望与大家分享。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM