【问题标题】:HTTP Post with Authorization header (CORS) on Wordpress在 Wordpress 上带有授权标头 (CORS) 的 HTTP 发布
【发布时间】:2018-07-22 22:47:18
【问题描述】:

我无法使用Authorization: Bearer -token- 发布内容,而且我几乎不怀疑我的服务器配置。 我在基于 wordpress 的服务器中使用 MAMP Pro。该服务器提供一个 API(这不是 Rest API wordpress 插件)。当我使用 Postman 时,这个 API 可以正常工作。

我的典型用例是:

  1. 在 POST 中使用用户名/密码作为参数从 https://front-end.com/login.html 发布到 https://back-end.com/api/users/auth
  2. 返回一个名为 myToken 的 JWT 令牌
  3. 在 POST 中从 https://front-end.com/index.html 发布到 https://back-end.com/api/alert,输入 1/input2 作为参数,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 步工作正常。使用 Postman 或我在 front-end.com 上的常规 Webapp 检索 JWT 令牌。

第 3 步适用于 Postman,我的表单已成功发布,我收到了 200。 但是当我将它与我的 WebApp 一起使用时,我无法通过预检 OPTION 请求。

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

经过测试:

A. MAMP 虚拟主机中的重写规则:

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

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

C.出于测试目的,删除“Authorization: Bearer”以查看请求是否发送到 POST(这并不奇怪)

D.尝试在.htaccess 中添加SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 ,有无之前的重写规则。

E.如上面的JS代码所述,尝试将Contet-Type硬设置为multipart,没有任何改进。

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

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

【问题讨论】:

    标签: javascript wordpress http jwt mamp


    【解决方案1】:

    如果它有一个副标题,它会是“使用服务工作者和 XHR 在另一个域上使用 JavaScript WebApp 在不使用插件的自定义 Wordpress 上进行 JWT 授权的故事”

    自动祝贺我自己,但特别感谢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. 在您的 Route 服务中,使用以下方法野蛮地绕过“addRoute”方法:

      $this->routes[] = [ltrim("/api/alert", '/'), [$myApiController, 'alertAction']];
      
    3. 在 API Controller $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. 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 实例根据 OPTIONS 请求执行特定操作 - 创建您的脚本需要允许预检请求的响应标头(在我的情况下允许“授权”自定义标头) - 创建常规请求处理程序(您的帖子或获取)。

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

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

    【讨论】:

      猜你喜欢
      • 2014-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      • 2017-08-07
      • 2016-12-28
      • 1970-01-01
      相关资源
      最近更新 更多