Nginx 如何在IPFS节点的认证api请求中使用带CORS的fetch
我想将经过身份验证的请求发送到IPFS api端点(在nginx后面),但是我很难同时获得CORS请求头和授权令牌 下面是我如何尝试的:Nginx 如何在IPFS节点的认证api请求中使用带CORS的fetch,nginx,cors,fetch,ipfs,Nginx,Cors,Fetch,Ipfs,我想将经过身份验证的请求发送到IPFS api端点(在nginx后面),但是我很难同时获得CORS请求头和授权令牌 下面是我如何尝试的: 让auth='dXNlcjpwYXNzd29yZA==' 让url为空https://url.of.api.endpoint.test' let headers=新的headers(); //set('Authorization','Basic${auth}`); 获取(url,{method:'POST',凭据:'include',headers:heade
让auth='dXNlcjpwYXNzd29yZA=='
让url为空https://url.of.api.endpoint.test'
let headers=新的headers();
//set('Authorization','Basic${auth}`);
获取(url,{method:'POST',凭据:'include',headers:headers})
.catch(console.error)
如果我添加一个凭据:“include”,那么我会得到403响应,因为浏览器没有发送授权头
如果我有一个“Authorization:basic xxx”标题,那么飞行前会停止向我发送正确的allow origin
同一原点上的页面不起作用:
而下面的页面没有:
在选项飞行前失败
XHR: OPTIONS https://ipfs.blockringtm.ml/api/v0/add?file=foobar.dat&cid-version=0
CORS Missing Allow Origin
OPTIONS https://ipfs.blockringtm.ml/api/v0/add?file=foobar.dat&cid-version=0
Status: 200 OK
Version: HTTP/2
Transferred: 324 B (0 B size)
Referrer Policy: no-referrer-when-downgrade
HTTP/2 200 OK
server: nginx
date: Sat, 27 Mar 2021 10:13:09 GMT
content-length: 0
vary: Origin
vary: Access-Control-Request-Method
vary: Access-Control-Request-Headers
strict-transport-security: max-age=15768000; includeSubDomains; preload
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
X-Firefox-Spdy: h2
XHRequest:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.5
Access-Control-Request-Headers: authorization
Access-Control-Request-Method: POST
Connection: keep-alive
Host: ipfs.blockringtm.ml
Origin: http://127.0.0.1:8080
Referer: http://127.0.0.1/
Sec-GPC: 1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:86.0) Gecko/20100101 Firefox/86.0
问题:如何使用fetch执行正确的认证CORS请求?
下面是更多的细节
我的IPFS节点配置了以下各项:
{“API”:{
“HTTPHeaders”:{
“访问控制允许凭据”:[
“对”
],
“访问控制允许标头”:[
授权,内容类型
],
“访问控制允许方法”:[
“得到”,
“职位”
],
“访问控制允许来源”:[
"http://127.0.0.1:8080",
"http://localhost:8088",
"https://webui.ipfs.io"
],
“访问控制公开标头”:[
“地点”
]
}
}
}
Nginx反向代理配置如下:
location /api/ {
proxy_pass http://michelc_ipfs_api;
proxy_read_timeout 600;
proxy_send_timeout 600;
#max upload size 2G
client_max_body_size 2048m;
# Adding missing CORS header from IPFS API response
if ($remote_method = 'OPTIONS') {
add_header Access-Control-Allow-Headers "Authorization";
}
limit_except OPTIONS {
auth_basic "Restricted Content";
auth_basic_user_file /home/michelc/htpasswd;
}
}
当我不使用凭据并将mode设置为“cors”时,它可以工作(需要一个本地ipfs守护程序在127.0.0.1:5001上运行api):
curl-i-X'选项“”http://127.0.0.1:5001/api/v0/add?file=foobar.dat&cid-版本=0'\
-H'来源:http://127.0.0.1:8080'-H“访问控制请求头:授权”
答案看起来是正确的:它具有正确的允许原点!:
HTTP/1.1 204 No Content
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:8080
Allow: OPTIONS, POST
Vary: Origin
Date: Sat, 27 Mar 2021 07:58:56 GMT
auth='c286YW5vbnltb3Vz'
curl-i-X POST“https://ipfs.blockringtm.ml/api/v0/add?file=key.json&wrap-当directory=true&quiet=true&quieter=true&cid version=0“-H”原点时:http://127.0.0.1:8080“-H”授权:基本${auth}“-F”文件=为什么,您好
回答看起来也不错:
server: nginx
date: Sat, 27 Mar 2021 09:25:37 GMT
content-type: application/json
vary: Accept-Encoding
access-control-allow-credentials: true
access-control-allow-headers: X-Stream-Output, X-Chunked-Output, X-Content-Length
access-control-allow-origin: http://127.0.0.1:8080
access-control-expose-headers: X-Stream-Output, X-Chunked-Output, X-Content-Length
trailer: X-Stream-Error
vary: Origin
x-chunked-output: 1
strict-transport-security: max-age=15768000; includeSubDomains; preload
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
{"Name":"QmWiziLpQ37PhV671gj6zPnWMGxdCKpBwdQVGbmWJmqFvE","Hash":"QmWiziLpQ37PhV671gj6zPnWMGxdCKpBwdQVGbmWJmqFvE","Size":"19"}
{"Name":"","Hash":"QmWZU5LLRcPmgZrvTkJuhRYmujEYCpvP8Efz1BqKM5AkRx","Size":"111"}
为了进一步调试,我安装了一个本地证书,让localhost使用SSL为我提供文件,并使用映射设置nginx,问题是我无法消除来自IPFS守护进程的坏头
因此,我尝试将最小值传递给IPFS,并在ngynx中处理COR:
# api keys :
map $http_x_apikey $api_realm {
default "";
"**secret1**" "IRQ";
"**secret2**" "key_id";
"**secret3" "ipns_key";
"**secret4**" "api_key";
"**secret5**" "key_add";
"**secret6**" "key_name";
"**secret7**" "key_provs";
"**secret8**" "key_config";
}
# $request_uri has the query part, $uri doesn't
map $request_uri $req_api {
default "not-an-api-req";
~^/api/v0/[^?]+?key=IRQ "${api_realm}line";
~^/api/v0/([^?]*) "${api_realm}_req_$1";
}
map $req_api $match_realm {
default no;
"IRQline" yes;
"key_id_req_id" yes;
"key_add_req_add" yes;
"key_provs_req_dht/findprovs" yes;
"key_name_req_name" yes;
"key_name_req_resolve" yes;
"key_config_req_config" yes;
"ipns_key_req_name/publish" yes;
"api_key_dht/findprovs" yes;
}
map $http_origin $allow_origin {
default no;
~http://127.0.0.1(?::[0-9]+)? yes;
~http://172.17.0.[0-9]+(?::[0-9]+)? yes;
~http://.*localhost: yes;
~https://gateway\..* yes;
~https://ipfs\..* yes;
"https://bl.ocks\.org" yes;
}
# pass origin if $allow_oring = no
map $allow_origin $proxy_pass_origin {
yes "";
no $http_origin;
default $http_origin;
}
# add_header Access-Control-Allow-Origin $http_origin
map $allow_origin $header_allow_origin {
default "";
yes $http_origin;
no "http://blockringtm.ml";
all "*";
}
map $allow_origin $header_allow_credential {
default "";
yes true;
}
# add_header Access-Control-Allow-Credentials true;
map $allow_origin $header_allow_credentials {
default "";
yes true;
}
# add_header Access-Control-Allow-Methods '$request_method';
map $allow_origin $header_request_method {
default "";
yes $request_method;
}
map $allow_origin $post_only {
default "OPTIONS";
yes "POST";
}
# add_header Access-Control-Allow-Headers "$http_access_control_request_headers";
map $allow_origin $header_request_headers {
default "";
yes $http_access_control_request_headers;
}
# authorization header
map $http_authorization $request_auth_header {
default "";
~Basic "authorization";
}
map $allow_origin $header_authorization {
default "";
yes $request_auth_header;
}
# global variables & maps
map $host $dbug { default 1; } # to allow more visibility !
map $dbug $x_name { default ""; 1 "Vern J. Guerrini"; }
map $dbug $x_loc_api { 1 "location $1"; default ""; }
map $dbug $x_req_api { 1 "$req_api"; default ""; }
map $dbug $x_api_realm { 1 "$api_realm"; default ""; }
map $dbug $x_match_realm { 1 "$match_realm"; default ""; }
map $dbug $x_allow_origin { 1 "$allow_origin"; default ""; }
map $dbug $x_uri { 1 "$uri"; default ""; }
map $dbug $x_request_uri { 1 "$request_uri"; default ""; }
map $request_uri $readonly {
default yes;
~^/api/v0/add no;
server {
...
proxy_set_header Authorization '';
proxy_set_header X-APIKey '';
# API key validation
location = /authorize_apikey {
internal;
if ($request_method = 'OPTIONS') {
return 204;
}
if ($api_realm = "") {
return 403; # Forbidden
}
if ($http_x_apikey = "") {
return 401; # Unauthorized
}
if ($match_realm = 'no') { return 200 "req_api and key_realm don't match"; }
return 204; # OK (no content)
}
...
# allow /api/v0/... with api-key or password
location ~* ^/api/v0/(add|resolve|object|name|dht|key/list|id) {
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_pass http://ipfs-api;
client_max_body_size 4m;
# debug headers
add_header x-dbug "$dbug";
#set $x_dbug "";
#if ($dbug = 1) { set $x_dbug "debug !"; }
add_header x-name "$x_name";
add_header x-loc_api "location matches $1";
add_header x-allow-origin "$allow_origin";
add_header x-api-realm "$api_realm";
add_header x-req-api "$x_req_api";
add_header x-header-requested "$header_request_headers";
# pass origin if not allowed here!
add_header x-proxy-pass-origin "$proxy_pass_origin";
proxy_set_header Origin "$proxy_pass_origin";
add_header Access-Control-Allow-Headers "x-apikey";
proxy_set_header Access-Control-Request-Headers "x-apikey"; # "$http_access_control_request_headers";
#proxy_set_header Access-Control-Request-Headers "$proxy_pass_request_headers";
# conditional headers (if $allow_origin = yes)
add_header Access-Control-Allow-Origin "$header_allow_origin";
add_header Access-Control-Allow-Credentials "$header_allow_credentials";
add_header Access-Control-Allow-Methods '$header_request_method';
add_header Access-Control-Allow-Headers "$header_request_headers";
#if ($request_method = 'OPTIONS') {
# add_header x-request-method "$request_method";
# add_header Access-Control-Allow-Credentials true;
# add_header Access-Control-Allow-Origin "$http_origin";
# add_header Access-Control-Allow-Methods 'POST';
# add_header Access-Control-Allow-Headers "$http_access_control_request_headers";
# return 200 'API $request_method call "$1" accepted from $http_origin';
#}
satisfy any;
auth_request /authorize_apikey;
limit_except OPTIONS {
auth_basic "Restricted API ($req_api)";
auth_basic_user_file /etc/nginx/htpasswd-api-add;
}
}
}
它仍然不工作,IPFS响应干扰nginx CORS
如何进行经过身份验证的ajax调用?
使用基本身份验证以外的其他身份验证:JWT、cookies?
我想更多地了解正确的方法,而不是快速破解,我们绕过CORS。鉴于您已经在Nginx级别为
/api/v0
添加了自定义路由和基本身份验证,我觉得您在Nginx上设置所有CORS头也会有更好的时间
这样,您就可以将所有逻辑放在一个地方,而不必在nginx和go-ipfs-config之间进行切换
另外,如果没有Nginx配置,就不可能给出有意义的答案。下次您填写这样的问题时,请将其包括在内。鉴于您已经在Nginx级别为
/api/v0
添加了自定义路由和基本身份验证,我觉得您在Nginx上设置所有CORS头的时间也会更好
这样,您就可以将所有逻辑放在一个地方,而不必在nginx和go-ipfs-config之间进行切换
另外,如果没有Nginx配置,就不可能给出有意义的答案。下次您填写这样的问题时,请将其包括在内。似乎IPFS守护进程忽略了
访问控制请求头,正如运行:`curl-i-X OPTIONS”“-H”Origin:“-H”访问控制请求头:authorization“``不返回任何关于允许头的信息!经过进一步调查,chromium上的脚本页面,而不是brave或firefox上的脚本页面。。。IPFS守护进程似乎忽略了访问控制请求头
,如下所示:`curl-i-X OPTIONS”“-H”Origin:“-H”访问控制请求头:authorization“``不返回任何关于允许头的信息!经过进一步调查,chromium上的脚本页面,而不是brave或firefox上的脚本页面。。。谢谢事实上,我希望cors只在一个地方,在我看来,让最终应用程序处理cors是合乎逻辑的(特别是我控制应用程序,而我不太容易控制nginx,因为它与一系列其他服务共享。让我编辑我的帖子来添加ningx config。谢谢……事实上,我只想将cors放在一个地方,在我看来,让最终应用程序处理它是合乎逻辑的(特别是我控制应用程序,而我控制nginx并不是那么容易,因为它与许多其他服务共享。让我编辑我的帖子,添加ningx配置。