I have configured a proxy_pass for an JAVA web service to enable cross origin. I can send a post request using the web service URL http://10.1.200.156:8080/ClientService/passwordReset/, but http://10.1.200.156/ClientService/passwordReset/ gives a 404 error. And client application gives, Response for preflight is invalid (redirect).
After searching the web I added proxy_set_header Host $http_host; to the Nginx configuration, but still no luck. Below, the Nginx configuration. Please help.
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;
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
server_name euca-172-16-10-214.eucalyptus.internal;
location /ClientService/passwordReset/ {
proxy_pass http://10.1.200.156:8080/ClientService/passwordReset/;
if ($request_method = 'OPTIONS') {
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;
}
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';
}
if ($request_method = 'GET') {
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';
}
}
}
}
You shouldn't include the URI when you're proxying. Try the following:
proxy_pass http://10.1.200.156:8080;
Related
Good day. On an Ubuntu 20.04 server, nginx is installed and a daemonized asp.net core web api project is running (serves as a back-end). On the back-end, I enabled the CORS policy and allowed full access to the server, that is, all requests from all origins must go through. However, the requests fail, referring to the CORS policy. Is it possible that the cloud network does not pass? Please tell me what's the matter.
My Program.cs:
`
var builder = WebApplication.CreateBuilder(args);
string connection = builder.Configuration.GetConnectionString("DatabaseConnection");
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(connection));
builder.Services.AddHttpContextAccessor();
builder.Services.AddSwaggerGen(options =>
{
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
{
Description = "Standard Authorization header using the Bearer scheme (\"bearer {token}\")",
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey
});
options.OperationFilter<SecurityRequirementsOperationFilter>();
});
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8
.GetBytes(builder.Configuration.GetSection("AppSettings:Token").Value)),
ValidateIssuer = false,
ValidateAudience = false
};
});
builder.Services.AddCors(options => options.AddPolicy(name: "NgOrigins",
policy =>
{
policy.WithOrigins("http://[website adress what i need]", "http://localhost:8080", "http://[website ip adress]", "http://[website ip adress]:7000").AllowAnyMethod().AllowAnyHeader();
}));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseCors("NgOrigins");
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
`
My current config for back-end:
server {
listen 81;
server_name [server domain name];
location / {
if ($request_method = 'OPTIONS') {
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,Cont> #
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-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Cont> 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, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Cont> add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
I tried adding special add-ons to /etc/nginx/sites-enabled/default and /etc/nginx/sites-aviable/default after location (default in this case is the back-end configuration of the project):
`
if ($request_method = 'OPTIONS') {
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';
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-Methods' 'GET, POST, 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-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
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';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
`
I looked for this error and just found solutions using history mode in vue and redirects in nginx location block. I did this like:
nginx:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name tests.test;
return 302 https://$server_name$request_uri;
}
server{
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
add_header 'Access-Control-Allow-Origin' '*';
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';
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
location / {
root /var/www/client/pvapp-client/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
...
And in my vue router:
Vue.use(Router)
const router = new Router({
mode: 'history',
routes: [{
path: '/',
name: 'home',
component: Home
},
{
path: '/app',
name: 'app',
component: Application
},
{
path: '/settings',
name: 'settings',
component: Settings
},
// otherwise redirect to home
{
path: '*',
redirect: '/'
}
]
})
And I still get the error from the server trying to serve a non existing route.
The vue error log is also warning:
"/var/www/client/pvapp-client/dist/app" failed (2: No such file or
directory)
Okay, I got it. Somehow the GET part of this setting has made the problems. Don't know why tho. Just comment it and everything worked fine:
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# Custom headers and headers various browsers *should* be OK with but aren't
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' 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-Methods' 'GET, POST, 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-Expose-Headers' 'Content-Length,Content-Range';
}
#if ($request_method = 'GET') {
# 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';
# add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
#}
I have a problem with my server developed in EXPRESS and hosted on NGINX.
I use passport.js for user authentication, even if I don't think this is the problem, and when I try to login from localhost I get an error while if I run it by uploading it to my domain I don't get it wrong and it works correctly, so I think it's a CORS problem blocking localhost requests.
NGINX default
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name api.mysite.com www.api.mysite.com;
location / {
proxy_pass https://localhost:3007; #whatever port your app runs on
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
if ($http_origin ~* (^https?://([^/]+\.)*(mysite)\.com$)) {
set $cors "true";
}
if ($http_origin ~* (^http?://([^/]+\.)*(localhost:3006))) {
set $cors "true";
}
if ($http_origin ~* (^https?://([^/]+\.)*(192.168.1.21:3006))) {
set $cors "true";
}
# Nginx doesn't support nested If statements. This is where things get slightly nasty.
# Determine the HTTP request method used
if ($request_method = 'OPTIONS') {
set $cors "${cors}options";
}
if ($request_method = 'GET') {
set $cors "${cors}get";
}
if ($request_method = 'POST') {
set $cors "${cors}post";
}
if ($cors = "true") {
# Catch all incase there's a request method we're not dealing with properly
add_header 'Access-Control-Allow-Origin' "$http_origin";
}
if ($cors = "trueget") {
add_header 'Access-Control-Allow-Origin' "$http_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';
}
if ($cors = "trueoptions") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($cors = "truepost") {
add_header 'Access-Control-Allow-Origin' "$http_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';
}
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
serverDev.js
const sessionParser = session({
saveUninitialized: false,
secret: 'secret',
resave: false,
cookie: {expires: 43200000, secure: false }
})
var privateKey = fs.readFileSync('ssl-cert/privkey.pem', 'utf8');
var certificate = fs.readFileSync('ssl-cert/fullchain.pem', 'utf8');
var credentials = { key: privateKey, cert: certificate };
var httpsServer = https.createServer(credentials,app);
routes.js
app.post('/Login', passport.authenticate('local-login', {
successRedirect : '/Profile',
failureRedirect : '/Login',
failureFlash : false
}),
function(req, res) {
if (req.body.remember) {
req.session.cookie.maxAge = 1000 * 60 * 3;
} else {
req.session.cookie.expires = false;
}
res.redirect('/Login');
});
app.get('/Profile', isLoggedIn, todoList.profile);
function isLoggedIn(req, res, next) {
console.log("isLoggedIn",req.isAuthenticated()) <--- THIS IS THE PROBLEM IN LOCALHOST RETURN ALWAYS FALSE
if (req.isAuthenticated())
return next();
res.redirect('/Login');
}
passport.js
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
connection.query("use `Users`");
connection.query("SELECT * FROM Accounts WHERE id = ? ",[id], function(err, rows){
if (err){
return done(err);
}
var user = rows[0];
done(err, user);
});
});
If anyone else had this problem I solved it by configuring the 'express-session' in this way
var session = require('express-session');
const sessionParser = session({
secret: 'your-secret',
resave: false,
saveUninitialized: true,
cookie: {
secure: true,
httpOnly: true,
sameSite: 'none',
maxAge: 1000 * 60 * 60 * 12 // milliseconds * seconds * minutes * hours
}
})
As per the MS doc, I need to set up a reverse proxy for my web api. The below is the nginx config with cors & reverse proxy settings:
server {
listen 80;
listen [::]:80;
server_name api.ZZZ.com;
set $cors '';
location / {
if ($http_origin ~ '^https?://(localhost|www\.ZZZ\.com|www\.ZZZ\.com|ZZZ\.com)') {
set $cors 'true';
}
if ($cors = 'true') {
add_header 'Access-Control-Allow-Origin' "$http_origin" 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,Width,X-Requested-With' always;
# required to be able to read Authorization header in frontend
add_header 'Access-Control-Expose-Headers' 'Authorization' always;
}
if ($request_method = 'OPTIONS') {
# Tell client that this pre-flight info is valid for 20 days
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
I also have the following in my startup.cs:
services.AddCors(options =>
{
options.AddPolicy(corsName, builder =>
{
builder.WithOrigins("http://www.ZZZ.com", "http://ZZZ.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
and later:
app.userCors(corsName);
But I am still getting the below CORS error:
Access to XMLHttpRequest at 'http://api.ZZZ.com/YYY' from origin 'http://www.ZZZ.com' 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.
Please help!
Can you try with SetIsOriginAllowedToAllowWildcardSubdomains configuration and adding wildcard subdomain? like this.
In the ConfigureServices method.
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.SetIsOriginAllowedToAllowWildcardSubdomains()
.WithOrigins("https://*.example.com","https://example.com")
.AllowAnyMethod()
.AllowCredentials()
.AllowAnyHeader()
.Build()
);
});
And in the Configure method
app.UseCors("CorsPolicy");
Restarting nginx :
# service nginx start
Starting nginx: nginx: [emerg] duplicate upstream "api" in /etc/nginx/sites-enabled/default:1
nginx: configuration file /etc/nginx/nginx.conf test failed
This is the config file :
upstream api{
least_conn;
server 127.0.0.1:5001 max_fails=2 fail_timeout=15s;
server 127.0.0.1:5002 max_fails=2 fail_timeout=15s;
server 127.0.0.1:5003 max_fails=2 fail_timeout=15s;
server 127.0.0.1:5004 max_fails=2 fail_timeout=15s;
}
server {
listen 192.168.10.33:80;
allow 192.168.0.0/20;
allow 127.0.0.1/32;
deny all;
server_name api api.my.intranet;
location ^~ (/images/|/css/|/javascripts/) {
root /var/www/myapi/public/;
expires 30m;
}
# serve all other stuff from appserver
location / {
if ($http_origin ~ (.*\.my\.intranet|.*\.my\.com) ) {
add_header 'Access-Control-Allow-Origin' $http_origin;
}
# add_header 'Access-Control-Allow-Origin' '*';
expires off;
proxy_pass http://api/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
}
}
server {
listen 175.30.33.14:80;
server_name api.my.com;
return 301 https://api.my.com$request_uri;
}
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/certs/my.com.2014.chain;
ssl_certificate_key /etc/ssl/private/my.com.2014.key;
server_tokens off;
server_name api api.my.com api.my.intranet;
location ^~ (/images/|/css/|/javascripts/) {
root /var/www/myapi/public/;
expires 30d;
}
# serve all other stuff from appserver
location / {
if ($http_origin ~ (.*\.my\.intranet|.*\.my\.com) ) {
add_header 'Access-Control-Allow-Origin' $http_origin;
}
# add_header 'Access-Control-Allow-Origin' '*';
expires off;
proxy_pass http://api/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
}
location /v2 {
rewrite ^/v2/(.*) /$1 break;
if ($http_origin ~ (.*\.my\.intranet|.*\.my\.com) ) {
add_header 'Access-Control-Allow-Origin' $http_origin;
}
# add_header 'Access-Control-Allow-Origin' '*';
expires off;
proxy_pass http://192.168.10.8:3000/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
Do you see any problem ?
a backup file: defuault.backup was in the same folder which created a conflict !