I'm trying to setup Grafana on top of nginx. Here's how my current setup is. Grafana is supposed to talk to both graphite and elastic search on the same server.
Here's my nginx configuration file. I'm not sure what's wrong in this configuration:
#graphite server block
server {
listen 8080 ;
access_log /var/log/nginx/graphite.access.log;
error_log /var/log/nginx/graphite.error.log;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
}
#grafana server block
server {
listen 9400;
access_log /var/log/nginx/grafana.access.log;
error_log /var/log/nginx/grafana.error.log;
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
add_header Access-Control-Allow-Origin 'http://54.123.456.789:9400';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, origin, accept';
add_header 'Access-Control-Allow-Credentials' 'true';
root /usr/share/grafana;
}
}
Now, whenever I try to run Grafana, it gives me the following error:
XMLHttpRequest cannot load http://54.123.456.789:8080/render. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://54.123.456.789:9400' is therefore not allowed access.
Can someone please help me out in this? Thanks in advance.
Try putting the four lines of Access-Control-Allow-* in the configuration of the graphite server.
To my mind, grafana is asking graphite and that's graphite who has to allow Grafana.
Ok I wasn't specifically setting up Graphana, but I was intending CORS to work with the auth_basic directive from nginx because such directive overrides any headers that you had before whenever authentication is required (When the server returns a 401 basically)
So after a copule hours of research I found this Gist: https://gist.github.com/oroce/8742704 which is specifically targetted to Graphana and possibly gives a complete answer to this question.
BUT for my particular purposes, which again were to combine auth_basic with CORS headers via add_header, my take away from that Gist is the following:
Your server location should follow a structure like the one below:
location / {
proxy_pass <PROXY_PASS_VALUE>;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Any additional headers and proxy configuration for the upstream...
# Remove the CORS Origin header if set by the upstream
proxy_hide_header 'Access-Control-Allow-Origin';
# Add our own set of CORS headers
# The origin specifically, when using ith with authentication CANNOT be set to * as per the spec, it must return 1 and only 1 value so to mimic "*"'s behavior we mirror the origin
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods
'GET,POST,PUT,DELETE,OPTIONS';
add_header Access-Control-Allow-Headers 'Authorization';
add_header Access-Control-Allow-Credentials 'true';
if ( $request_method = 'OPTIONS' ) {
# If request method is options we immediately return with 200 OK
# If we didn't do this then the headers would be overwritten by the auth_basic directive when Browser pre-flight requests are made
return 200;
}
# This should be set AFTER the headers and the OPTIONS methos are taken care of
auth_basic 'Restricted';
auth_basic_user_file <HTPASSD_FILE_PATH>;
}
Then when using this from a browser environment, you could issue the following:
fetch(
'<URL>',
{
method: 'POST',
body: <YOUR_BODY_OBJECT>,
// This must be set for BASIC Auth to work with CORS
credentials: 'include'
}
)
.then( response => response.json() )
.then( data => {
console.log( data );
} );
Related
for the past 3 days i've being searching the internet for solutions to CORS error to no success, i'm building a react app that access data from remote resource the remote resource is built with yii2 rest API, after alot search the suggestion was that i should configure nginx as a proxy ser and below is what I got so far
server {
set $project_root /var/www/html/
set $root /usr/share/nginx/html;
charset utf-8;
server_name api.checkstall.com;
root $project_root;
index index.html index.htm index.php;
add_header 'Access-Control-Allow-Origin' 'https://checkstall.com';
add_header 'Access-Control-Allow-Credentials' 'true';
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';
location / {
if (-f $root/api_maintenance_on.html) {
return 503;
}
rewrite ^/(.*)$ /index.php?$args&request_filename=$1 last;
try_files $uri $uri/ #rewrite;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 86400;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_redirect off;
proxy_set_header host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-forward-for $proxy_add_x_forwarded_for;
proxy_pass https://api.checkstall.com;
}
}
}
After this set up few things changes:
The unauthenticated request with GET method works
The login method with post didn't work
signup methos with post on different controller with lodin didn't work either
without this setup nothing works at all
My observation was that for the /auth/login route no response header infortion was received, the server didn't hadd any response to the header
The above Images is before and after implementing proxy pass in nginx
I'm open to solutions either from both frontend, backend or server side and help would be appreciated
I'm trying to create a mock e-commerce site using React and my backend is built with Strapi. I have my backend on an nginx VPS. When I view my website online, no products are being populated and my console is showing this error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at https://.../api/categories?populate=.
(Reason: CORS request did not succeed). Status code: (null).
I have added code to my Nginx configuration file
/etc/nginx/sites-available/default
The code I added was:
location /api {
add_header 'Access-Control-Allow-Origin' '*';
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;
}
I'm still getting the same error message.
Any ideas on what could resolve this for me?
I'm really new to setting up a VPS (first time trying it) and I would also appreciate any advice on how to best learn how to work with servers - any online resources or teachers would be great.
Thanks!
This afternoon I was make some small adaptations to my react app. However, when trying to fetch information from my elasticsearch server, I receive a strict-origin-when-cross-origin error. I have received CORS errors in the past and was always able to deal with them in a certain way, but this time I am quit stuck.
My set up:
I have the react app, using axios, making the following get request:
const authorization = process.env.REACT_APP_ELASTICSEARCH_AUTHORIZATION;
const header = {
'Authorization': authorization,
}
axios.get(`${path}/${searchIndex}/_search`,
{headers: header}
The request is then send to my proxy server running nginx.
The setting there are the following:
location /somelocation/ {
proxy_pass https://someip:someport/;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
proxy_hide_header Access-Control-Allow-Headers;
add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
add_header Access-Control-Allow-Credentials true;
proxy_pass_header Authorization;
}
On the elasticsearch server I have the following CORS settings:
http.cors.enabled: true
http.cors.allow-credentials: true
http.cors.allow-origin: '*'
http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length, Authorization, Access-Control-Allow-Headers, Accept
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
Making requests, using the path that the react app is using, from postman works perfectly fine. I can also perform the request from my browser, after passing the necessary username + password. Only the react app (in development running on localhost) does not seem to work.
From https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors I understand:
strict-origin-when-cross-origin (default)
Send the origin, path, and querystring when performing a same-origin request. For cross-origin requests send the origin (only) when the protocol security level stays same (HTTPS→HTTPS). Don't send the Referer header to less secure destinations (HTTPS→HTTP).
I thought that maybe the problem was situated with the fact that the app runs on HTTP and not HTTPS, but running the app via 'HTTPS=true npm start' did not solve the problem. I have tried different tweaks, both on the request side (axios) as in nginx or in the es yml file, but nothing seems to work. Thank you and kind regards for your help.
EDIT:
included screenshots now as well:
Ok I was able to solve the error in the course of this afternoon. First of all, not all the error messages were showing in my console, which made it fo course more difficult to detect the error. As pointed out correctly above, the error message I was seeing, was just a generic message. In my console I needed to update the settings to the following:
After that the complete CORS errors were visible, which required me to make some changes, both to the NGINX proxy server and the elasticsearch server.
The first error was: "header field authorization is not allowed by Access-Control-Allow-Headers in preflight response"
Although the elasticsearch server allowed the Authorization header, this was -correct me if I am wrong- not properly passed on by the NGINX proxy server, since the settings there were: "proxy_hide_header Access-Control-Allow-Headers;"
I changed the NGINX settings to:
proxy_pass https://******:9200/;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_header Access-Control-Allow-Origin;
proxy_pass_header Access-Control-Allow-Methods;
# proxy_hide_header Access-Control-Allow-Headers;
proxy_pass_header Access-Control-Allow-Headers;
# add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
# add_header Access-Control-Allow-Credentials true;
proxy_pass_header Authorization;
The lines that are commented out are the old configurations.
Attempting a several new requests, other CORS policies were shown, such as access-control-allow-methods is not allowed by Access-control-Allow-Headers, access-control-allow-origin is not allowed by Access-Control-Allow-Headers,... At that point the errors were clearly indicating what to do, namely adding these fields to the Access-Control-Allow-Headers section in the elasticsearch configuration file.
After completing everything, the elasticsearch config yml file looks like this:
http.cors.enabled: true
http.cors.allow-credentials: true
http.cors.allow-origin: '*'
http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length, Authorization, Access-Control-Allow-Headers, Accept, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Allow-Credentials
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
So I added: Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Allow-Credentials.
Thanks everyone for helping me out, I post this answer so it might be used for future purposes. Feel free to further correct me.
Add both lines to the below file
/etc/nginx/sites-available/yours_conf_file
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
and restart nginx server
sudo systemctl restart nginx
This question already has answers here:
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
(36 answers)
Closed 3 years ago.
I create API, BackEnd and Frontend website.
I used Express for API, BackEnd - FrontEnd using ReactJs
So in my local everything works. But when i deployed to server This error message show
Access to XMLHttpRequest at 'http://domain/headline' from origin 'http://domain' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.
and
Access to XMLHttpRequest at 'http://domain/marketData/snack' from origin 'http://domain' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
in ReactJs im using axios for getting data.
And in my nginx server i already set
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' 'http://domain';
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';
}
}
Did i missed something?
Install cors first from npm by npm i cors in your api server.
Then in your app.js or server.js or index.js (main file that you create http service) use these line of code
const cors = require('cors');
app.use(cors());
app.options('*', cors());
So I have been pulling my hair out for a couple of days now. I have a backend server, using Spring-boot with Rest API
This server is called from a frontend interface using AngularJS, also handled by Nginx.
Everything is running locally. Whenever I try to make a request from the fronted to the backend, I get the following error:
I know what you think: Easy, just add add_header 'Access-Control-Allow-Origin' 'http://[MY_IP]'; to your nginx.conf file on the backend, and everything will work, like here. or here.
But it doesn't. I tried everything, moving it to different locations, putting a '*' instead of the address, enabling and disabling SSL... The only thing that works is when I manually disable Cross-Origin restrictions in the browser. And the best part is that when I do disable those restrictions, I can see the Access-Control-Allow-Origin header set to http://[MY_IP] in the debug console of my browser!
Any idea of what might be going wrong?
Here is my nginx.conf file:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Here is my /etc/nginx/sites-enabled/default.conf file:
upstream backend_api {
server 10.34.18.2:8080;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html/;
index index.html;
client_max_body_size 5M;
location /todos {
access_log /var/log/nginx/todos.backend.access.log;
error_log /var/log/nginx/todos.backend.error.log;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://backend_api;
}
location / {
access_log /var/log/nginx/todos.frontend.access.log;
error_log /var/log/nginx/todos.frontend.error.log;
try_files $uri $uri/ =404;
}
}
I create a symbolic link:
ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
I am not sure if this will make the cors work, but it may help getting near to the solution:
Access-Control-Allow-Origin: http://[MY_IP] is not the only header you need to take care of.
As the Content-Type is application/json and also, you are not using non simple headers, you will also have to give specific permission to Content-Type header, the same with Accept-Encoding and DNT
Access-Control-Allow-Headers: Content-Type, Accept-Encoding, DNT
I am not sure about this one for this specific GET, but in any case also the allowed methods:
Access-Control-Allow-Methods: GET
And if you are sending cookies, authorization header, or cliente certificates for authentication:
Access-Control-Allow-Credentials: true
I don't think it is your current case, but please note that returning Access-Control-Allow-Credentials: true and blindly replicating the received Origin in the Access-Control-Allow-Origin response, enables any site to access your server impersonating the owner of the credentials.
And just in case you are tempted, ACAO: * with ACAC: true will not work as per specification.
You may also have to take care of the OPTIONS method called during a cors preflight which shold be in line with what the actual call will respond.
And remember that not returning one of these headers is the way to deny it.
Ref: CORS - MDN