Wordpress上带有授权标头(CORS)的HTTP Post



我无法使用Authorization: Bearer -token-发布某些东西,我几乎不怀疑我的服务器配置。 我正在使用MAMP Pro,在基于wordpress的服务器中。该服务器提供了一个API(这不是Rest API wordpress插件)。当我使用邮递员时,此 API 工作正常。

我的典型用例是:

  1. 在 POST 中从 https://front-end.com/login.html 发布到 https://back-end.com/api/users/auth,用户名/pwd 作为参数。
  2. 返回一个名为myToken的 JWT 令牌
  3. 在 POST 中从 https://front-end.com/index.html 发布到 https://back-end.com/api/alert,输入 1/输入 2 作为参数,Authorization: Bearer <myToken>作为标头。

步骤 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);

步骤 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);
});

步骤 1 工作正常。JWT 令牌是使用 Postman 或我在 front-end.com 上的常规 Web 应用程序检索的。

第 3 步适用于邮递员,我的表格已成功发布,我收到了 200。 但是当我在 WebApp 中使用它时,我无法传递预检选项请求。

请注意,我还使用 mockable.io(也是https)模拟了我的API,并且请求成功通过;这在我们的例子中并不重要,但这就是为什么我怀疑服务器配置错误的原因。

测试:

一个。 在 MAMP 虚拟主机中重写规则:

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

B.在我的WordPress服务器的htaccess中重写规则(同上,在现有的重写规则之后推送)

三.出于测试目的,删除了"授权:持有者"以查看请求是否转到 POST(它毫不奇怪)

D. 尝试在 .htaccess 中添加SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 ,无论是否使用以前的重写规则。

E.如上面的JS代码中所述,尝试将Contet类型硬设置为多部分,但没有改进。

F.尝试在端点中添加/API_ALERT以防万一wordpress进行愚蠢的重定向(之前经历过)

我现在完全不知道去哪里寻找。我怀疑要么是Apache配置阻止了授权,要么是Wordpress弄乱了Cors或授权。

如果这有一个副标题,那就是"在不使用插件的自定义WordPress上使用JWT授权的故事,在另一个域上使用Service Workers和XHR的JavaScript WebApp">

自动祝贺我自己,但特别感谢 https://www.html5rocks.com/en/tutorials/cors/,提供了有关服务器和脚本如何交互的清晰信息。

使用Wordpress,我的解决方案是(我没有改变我的JS代码):

  1. #BEGIN WordPress语句之前添加以下内容

    <IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTP:Authorization} ^(.*)
    RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
    </IfModule>
    
  2. 在您的路由服务中,使用以下方法野蛮地绕过"addRoute"方法:

    $this->routes[] = [ltrim("/api/alert", '/'), [$myApiController, 'alertAction']];
    
  3. 在 API 控制器$myApiControler中创建入口点函数警报操作

    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. handleOptionsMethod()方法中创建适当的选项响应,其中包含所需的标头

    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. 在 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();
    }
    

然而,基本上: - 允许您的服务器读取其他 HTTP 信息 - 允许你的wordpress实例在选项请求上做特定的事情 - 创建脚本允许预检请求所需的响应标头(在我的情况下允许"授权"自定义标头) - 创建常规请求处理程序(您的帖子或 get)。

希望这对你们中的一些人有所帮助。

我问题的最后一部分是,现在 POST 请求成功触发,服务工作者不起作用,因此我无法访问"响应"并正确处理它。但我已经向前迈出了一大步,想与你们中的一些人分享。

最新更新