Verify a jwt token with openresty lua-nginx-module every request - nginx

I made react website, that request a remote http API (managed by a third party).
My website is using https with a valide certificate.
The third party API is "secured" by a simple GET param in the URL , "?key=XXXX" . to check if we can access the endpoint.
The third party API has CORS
To be able to request the http remote API I made a nginx reverse proxy .
With extra header to allow CORS.
And to secure a little bit more I added JWT Token verification .
All is working fine , if the Header Authorization Bearer with token is invalid or unset i cannot access the third party api. nginx is blocking me.
But as soon as I provide a valid Authorization Header once , any further request will PASS. the token is not checked anymore , even if i make the request from a different device with different IP.
How to check the token for every single request i make
Here is my nginx conf
server {
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
location / {
default_type application/json;
return 200 '{"message": "Endpoint is required"}';
}
location ^~ /api/ {
include jwt.conf;
include headers.conf;
set $args $args&key={KEY};
proxy_pass http://www.third-party.com/api/;
}
}
Here is my jwt.conf file , I am using the openresty lua-nginx-module
access_by_lua_block {
local jwt = require "resty.jwt"
local jwt_obj = jwt:verify("{SECRET}", token, claim_spec)
local auth_header = ngx.var.http_Authorization
if auth_header then
_, _, token = string.find(auth_header, "Bearer%s+(.+)")
end
if token == nil then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.header.content_type = "application/json; charset=utf-8"
ngx.say("{\"error\": \"missing JWT token or Authorization header\"}")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
if not jwt_obj["verified"] then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.log(ngx.WARN, jwt_obj.reason)
ngx.header.content_type = "application/json; charset=utf-8"
ngx.say("{\"error\": \"" .. jwt_obj.reason .. "\"}")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
}
And to be complete , my headers.conf
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_buffers 32 16k;
proxy_busy_buffers_size 64k;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000;
return 204;
}
# Ajouter les headers de contrôle d'accès CORS
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, PUT, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;

Here:
_, _, token = string.find(auth_header, "Bearer%s+(.+)")
you declare token as a global variable. It is strongly discouraged:
Note that the use of global Lua variables is strongly discouraged, as it may lead to unexpected race conditions between concurrent requests.
It explains why subsequent requests are authorized if you do not include the Authorization header -- the token from the initial request is "cached" in the Lua global state.
Moreover, here:
local jwt_obj = jwt:verify("{SECRET}", token, claim_spec)
you reference the token variable before it is declared.
The correct code is something like this:
local jwt = require "resty.jwt"
local auth_header = ngx.var.http_Authorization
-- `local token` is equvalent to `local token = nil`
local token
if auth_header then
token = string.match(auth_header, "Bearer%s+(.+)")
end
if token == nil then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.header.content_type = "application/json; charset=utf-8"
ngx.say("{\"error\": \"missing JWT token or Authorization header\"}")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- BTW, where do the `claim_spec` come from?
local jwt_obj = jwt:verify("{SECRET}", token, claim_spec)
if not jwt_obj["verified"] then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.log(ngx.WARN, jwt_obj.reason)
ngx.header.content_type = "application/json; charset=utf-8"
ngx.say("{\"error\": \"" .. jwt_obj.reason .. "\"}")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end

Related

Cookie has been rejected because it is in a cross-site context (Nginx, Nextjs, Rocket)

My development workflow is as follow:
I access the frontend via https://client.my-project:3001. Nginx proxies it to nextjs's local server at localhost:3000. In a react component there's a function handlesubmit in which fetch sends a post request to the backend. I use Nginx as a reverse proxy between nextjs and the backend. The backend's response contains a cookie configured with secure, HttpOnly, same site strict. The cookie is rejected in the browser with the following message cookie “id” has been rejected because it is in a cross-site context and its “samesite” is “lax” or “strict”.
Here is the conf file for nginx:
upstream api {
server localhost:8000;
}
upstream client {
server localhost:3000;
}
server {
listen 3001 ssl;
server_name client.my-project;
ssl_certificate /client/client.my-project.pem;
ssl_certificate_key /client/client.my-project.pem;
location / {
proxy_pass http://client;
}
location /_next/webpack-hmr {
proxy_pass http://client/_next/webpack-hmr;
proxy_http_version 1.1;
proxy_set_header upgrade $http_upgrade;
proxy_set_header connection "upgrade";
}
}
server {
if ($http_origin = https://client.my-project:3001) {
set $allowed_origin 'https://client.my-project:3001';
}
listen 4545 ssl;
server_name api.my-project;
ssl_certificate /api/api.my-project.pem;
ssl_certificate_key /api/api.my-project-key.pem;
location / {
add_header 'access-control-allow-origin' $allowed_origin always;
add_header 'access-control-allow-credentials' 'true' always;
add_header 'access-control-allow-headers' 'authorization,accept,origin,dnt,x-customheader,keep-alive,user-agent,
x-requested-with,if-modified-since,cache-control,content-type,content-range,range';
add_header 'access-control-allow-methods' 'get,post,options,put,delete,patch';
proxy_pass https://api;
}
}
Here is how I use fetch to send a POST request to the backend.
const response = await fetch(`${process.env.NEXT_PUBLIC_API}/user`, {
mode: 'cors',
method: 'POST',
body: formData,
credentials: 'include'
});
And here is how the cookie is created in the backend:
let cookie = Cookie::build("id", session_id)
.secure(true)
.http_only(true)
.same_site(SameSite::Strict)
.finish();
I want to avoid setting the cookie to same site none.

django-cors-headers and nginx config: preflight response missing CORS headers

I use django-cors-headers 3.1.1 for handling the requests and responses between my Django-backend and Javascript-frontend apps. Transport is non-secured (i.e. http, not https).
When hosted locally, everything works fine. But after deploying on the server, I stopped seeing the CORS headers.
Here are headers in development:
and in production:
Error message:
Access to XMLHttpRequest at 'http://[HOST_IP]/api/assets/' from origin 'http://my_custom_domain.eu' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
My nginx configurations looks as follows:
server {
listen 80;
server_name [HOST_IP];
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/[path_to_app]/app.sock;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, PUT, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 86400;
if ($request_method = 'OPTIONS') {
add_header 'Content-Type' 'text/html; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'PUT') {
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
location /static/ {
autoindex on;
alias /home/ubuntu/[path_to_app]/site/static/;
}
}
The django-cors-headers’ settings are now identical in development and in production:
INSTALLED_APPS = (
…
"corsheaders",
…
)
MIDDLEWARE = [
…
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
…
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = ['DELETE','GET','OPTIONS','PATCH','POST','PUT']
On the client side I tried to add ‘'Access-Control-Request-Method’: ‘PUT’ header, but this was refused by the browser. There’s noting unusual in the client call:
axios({
method: 'put',
url: `${this.backendUrl}/api/assets/`,
data: formData,
headers: {
'Content-Type': 'application/octet-stream',
}
})
Also, I’m trying to host on the Amazon AWS EC2 for the first time, so perhaps there is some required AWS configuration I am not aware of. For example, is it necessary to enable CORS using the API Gateway? The documentation does not say so (‘If you are using the API Gateway Import API, you can set up CORS support using an OpenAPI file’).
The frontend application is hosted on a S3 bucket with the following CORS policy:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
What am I missing here? Is there some needed server-side (nginx especially) configuration?
Some other solutions I’ve tried:
I have doubts, whether the request/response origin is correct (e.g. APPEND_SLASH variable). But if this is the case, shouldn’t an error be raised when hosted locally?
I also tried setting proxy headers as in this question, but without knowing nginx very well this was doomed to fail.
I managed to solve this issue by changing 3 things:
AWS
I noticed that AWS documentation states:
CORS is already enabled for the Amazon EC2 API, and is ready for you
to use. You do not need to perform any additional configuration steps
to start using this feature. There is no change to the way that you
make calls to the Amazon EC2 API; they must still be signed with valid
AWS credentials to ensure that AWS can authenticate the requestor. […]
This is usually handled by AWS SDK or CLI, but in my case I used none of them, so I had to add AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. In my case I simply used aws4 library:
axios(aws4.sign({
accessKeyId: this.awsAccessKey,
secretAccessKey: this.awsSecretAccessKey,
method: 'put',
url: `${this.backendUrl}/api/assets/`,
data: formData,
body: JSON.stringify(formData),
service: 'ec2',
region: 'eu-central-1',
path: '/',
headers: {
'Content-Type': 'application/octet-stream'
}
}))
I’ve seen plenty of examples how to add AWS Signature v.4 without any additional dependency, though.
NGINX
In nginx configuration I placed all add_headers statements into conditional code-blocks. Idea came from this post.
server {
listen 80;
server_name [HOST_IP];
location / {
include proxy_params;
proxy_pass http://unix:/home/ubuntu/[path_to_app]/app.sock;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, PUT, OPTIONS, POST, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Amz-Date';
add_header 'Access-Control-Max-Age' 86400;
add_header 'Content-Type' 'text/html; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'PUT') {
add_header 'Access-Control-Allow-Methods' 'GET, PUT, OPTIONS, POST, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Amz-Date';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, PUT, OPTIONS, POST, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,X-Amz-Date';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
location /static/ {
autoindex on;
alias /home/ubuntu/analizy/be/site/static/;
}
}
Django-cors-header
Here it sufficed to add non-default headers.
from corsheaders.defaults import default_headers
CORS_ALLOW_HEADERS = list(default_headers) + [
'X-Amz-Date',
]
Hope that this will help someone.

CORS problems in microservices architecture

After a lot of searches and tries, I have decided to post my problems around CORS.
Context
I have a web site on a local server (NGINX), located on a PI. My web site deals with a microservice through REST API.
My PI is behind my Freebox (French internet box), which redirect a specific port (ex : 28800) to the local # of my pi. FYI, I don't have (and don't want) a fixed IP. And I share my IP with others users. So, I have a range of ports between 20000 and 30000 (approximatively).
And I have a NO-IP hostname, pointed on my freebox IP completed with the specifc port.
To resume:
User -> mysite.no-ip.com ---(Translation NO-IP)---> 91.123.456.678:specifcport ---- (Redirect to my pi) ---> 192.168.0.30:80----(nginx)--->index.html
What I can do:
In my nginx site conf, I set a location /core.
When I do
mysite.no-ip.com/core/blabla, I well obtain the blabla treatment.
No problem!!
Here is my problem:
When I click on the button which launches the blabla action (throught an AJAX POST on mysite.no-ip.comm/core/blabla), I get a CORS failure.
I have tried to modify my nginx configuration, adding headers depends of OPTIONS/GET/POST request type. Nothing appends.
But, I find that my nginx is never touched by the request /core/blabla if this one is send by button. I have a CORS answer thrown by an APACHE Server. And I didn't install any APACHE Server. So, perhaps, it's a server hidden in my Freebox? Don't know how to set it to allow CORS request.
Here is a snippet of my nginx config file
server {
listen 80;
server_name mysite.no-ip.com
location / {
alias /path/to/root/production/folder/here;
}
location /core/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
proxy_pass http://localhost:8002/;
}
}
Thank you for your help.
Ok, Fix my problem which was solved by a combination of my Internet provider box configuration and addition of some headers on my request.

Axios send wrong cookies (CORS)

I am using local development server (on my computer) for frontend. Backend is located on another server and I sending requests from frontend to backend using CORS.
It works ok, but when I passing cookies from frontend, It passed incorrect: namely the csrf token is different from what is stored in cookies.
Examples:
Cookies on Chrome dev tools, Application tab: csrf_token: b2o3q06llj
Request headers:
As you can see, header Cookie is different from data viewed on Application tab. X-Csrf-Token is correct, but Cookie header is wrong. It must contain csrf_token which is available on Dev tools > Application > Storage > Cookies
CORS setup in Nginx config (remote server):
if ($request_method ~* "(GET|POST)") {
add_header 'Access-Control-Allow-Origin' 'http://192.168.1.127:3000' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range, X-Csrf-Token, Cache-Control' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
# Preflighted requests
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" 'http://192.168.1.127:3000' always;
add_header "Access-Control-Allow-Credentials" 'true' always;
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD" always;
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Csrf-Token, Cache-Control" always;
return 204;
}
Axios setup:
axios.create({
baseURL: window.location.protocol + '//' +window.location.hostname + (window.location.port ? ':' + window.location.port : '') + '/data',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Csrf-Token': <token>,
'X-Requested-With': 'XMLHttpRequest'
},
withCredentials: true
});
I can not understand what the problem is. Why does axios not send correct cookies?

NGINX Reverse Proxy and Access-Control-Allow-Origin issue

I'm configuring an NGINX Reverse Proxy.
On the browser I go to:
client url: https://www.hollywood.com
Then the web page above needs to do requests to:
server url: https://server.hollywood.com/api/auth/login
This is the configuration corresponding to: server.hollywood.com:
server {
listen 443 ssl;
server_name server.hollywood.com;
# add_header 'Access-Control-Allow-Origin' "https://www.hollywood.com" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
ssl_certificate ../ssl/lets-encrypt/hollywood.com.crt;
ssl_certificate_key ../ssl/lets-encrypt/hollywood.com.key;
location /
{
proxy_pass http://localhost:9201;
include "../proxy_params.conf";
}
}
Experiment 1:
With the Access-Control-Allow-Origin line commented out, when I access to:
client url: https://www.hollywood.com
I get the following error on the browser console (Chrome in my case):
POST https://server.hollywood.com/api/auth/login/local 502 (Bad Gateway)
(index):1 Failed to load https://server.hollywood.com/api/auth/login/local: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.hollywood.com' is therefore not allowed access. The response had HTTP status code 502.
Experiment 2:
If I enable the Access-Control-Allow-Origin line above, then I get on the browser terminal:
Failed to load https://server.hollywood.com/api/auth/login/local: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains multiple values '*, https://www.hollywood.com', but only one is allowed. Origin 'https://www.hollywood.com' is therefore not allowed access.
I don't know why multiple when before that header was not present???
Experiment 3:
In the other hand, if I go directly on the browser to the:
server url: https://server.hollywood.com/api/auth/login
with the Access-Control-Allow-Origin line commented out, I get the following (on the Network section):
Response Headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 139
Content-Security-Policy: default-src 'self'
Content-Type: text/html; charset=utf-8
Date: Sat, 09 Jun 2018 06:34:00 GMT
Server: nginx/1.13.12
X-Content-Type-Options: nosniff
Before I got: "No 'Access-Control-Allow-Origin' header is present on the requested resource." but now I see above that field is in there on the Response Headers.
Experiment 4:
If I enable again the Access-Control-Allow-Origin line above, then I get the following (on the Network section):
Response Headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: https://www.hollywood.com
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 139
Content-Security-Policy: default-src 'self'
Content-Type: text/html; charset=utf-8
Date: Sat, 09 Jun 2018 06:34:58 GMT
Server: nginx/1.13.12
X-Content-Type-Options: nosniff
Now I get two times the field: Access-Control-Allow-Origin.
Do you have any idea why my first 2 experiments are failing getting the errors relative to: Access-Control-Allow-Origin?
Thanks!
It could be that the server behind your proxy_pass was setting the Access-Control-Allow-Origin header as well.
For what it's worth for future readers with a similar problem, I found that my node.js server was passing an Access-Control-Allow-Origin: '*' header for some reason, as well as the actual header I'd set in node.js to restrict CORS. When commenting out my node.js cors middleware, the Access-Control-Allow-Origin: '*' header still remained.
To resolve this, I used the nginx proxy_hide_header directive to remove the header coming from node.js and manually adding it as it should be:
# proxying the
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# local node.js server
upstream websocket {
server 127.0.0.1:3000;
}
server {
server_name ...;
# ...;
# add the header here
add_header Access-Control-Allow-Origin https://www.hollywood.com;
# Websockets config
location /socket.io/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# do not pass the CORS header from the response of the proxied server to the
# client
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_pass http://websocket;
proxy_http_version 1.1;
}
location / {
# ...
try_files $uri /index.html;
}
}
Googling this issue was pretty hard since most people are trying to fix CORS by making the Access-Control wide open! Here was another issue with similar problems:
https://serverfault.com/questions/751678/how-can-i-replace-access-control-allow-origin-header-in-proxy-response-with-ngin
Try this configuration:
server {
listen 443 ssl;
server_name server.hollywood.com;
ssl_certificate ../ssl/lets-encrypt/hollywood.com.crt;
ssl_certificate_key ../ssl/lets-encrypt/hollywood.com.key;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
proxy_pass http://localhost:9201;
include "../proxy_params.conf";
}
if ($request_method = 'GET') {
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
proxy_pass http://localhost:9201;
include "../proxy_params.conf";
}
}
}
Code based on https://enable-cors.org/server_nginx.html
Hope it helps.

Resources