我无法使用Authorization: Bearer -token-
实现POST一些东西,我几乎不怀疑我的服务器配置。我在基于wordpress的服务器中使用MAMP Pro。该服务器提供API(这不是Rest API wordpress插件)。当我使用Postman时,此API工作正常。
我的典型用例是:
myToken
的JWT标记Authorization: Bearer <myToken>
作为Header。第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或我的常规Webapp在front-end.com上检索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.出于测试目的,删除“授权:持有者”以查看请求是否进入POST(并且毫不奇怪)
D.试图在.htaccess中添加SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
,无论是否有以前的重写规则。
E.如上面的JS代码所述,尝试将Content-Type硬件设置为multipart,没有任何改进。
F.尝试在端点API_ALERT中添加/,以防万一wordpress执行愚蠢的重定向(之前经历过)
我现在完全不知道在哪里寻找。我怀疑是Apache配置阻止了授权,还是Wordpress搞乱了Cors或Authorization。
如果这有一个副标题,那就是“使用无需插件的自定义Wordpress上的JWT授权故事,使用Service Workers和XHR在另一个域上使用JavaScript WebApp”
自我祝贺自己,但特别感谢https://www.html5rocks.com/en/tutorials/cors/,提供有关服务器和脚本如何交互的清晰信息。
使用Wordpress,我的解决方案是(我的JS代码没有改变):
#BEGIN WordPress
语句之前添加以下内容
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
</IfModule>
$this->routes[] = [ltrim("/api/alert", '/'), [$myApiController, 'alertAction']];
$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;
}
}
}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();
}
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不起作用,因此我无法访问“响应”并正确处理它。但我已向前迈出了一大步,并想与你们中的一些人分享。