CORS 仅阻止 localhost 请求

Posted

技术标签:

【中文标题】CORS 仅阻止 localhost 请求【英文标题】:CORS block only localhost request 【发布时间】:2021-02-04 04:47:34 【问题描述】:

我使用 EXPRESS 开发并托管在 nginx 上的服务器存在问题。

我使用 passport.js 进行用户身份验证,即使我认为这不是问题,当我尝试从 localhost 登录时出现错误,而如果我通过将其上传到我的域来运行它,我不会'没有弄错它并且可以正常工作,所以我认为这是阻止 localhost 请求的 CORS 问题。

NGINX 默认

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 "$corsoptions";
        
        if ($request_method = 'GET') 
                set $cors "$corsget";
        
        if ($request_method = 'POST') 
                set $cors "$corspost";
        

        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);
    );
);

【问题讨论】:

你用过https://localhost吗? 我猜你是使用 SSL 的 api 域,然后你切换到使用 localhost 和 SSL,它得到了错误 我尝试了两种解决方案,但问题仍然存在 你应该使用http://localhost,你能分享一下监听80端口的nginx部分 我在 React JS 中开发我不能在没有端口的情况下使用localhost,我唯一能做的就是像这样使用端口 80:“start”:“PORT=80 HTTPS=true SSL_CRT_FILE=. /.cert/cert.pem SSL_KEY_FILE=./.cert/key.pem react-scripts start" 【参考方案1】:

如果其他人有这个问题,我通过这种方式配置 'express-session' 解决了它

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
        
)

【讨论】:

以上是关于CORS 仅阻止 localhost 请求的主要内容,如果未能解决你的问题,请参考以下文章

对 Django 服务器 CORS 的获取请求仅阻止一个视图

跨源请求被阻止的 CORS - 使用角度 cli 解决 [仅限开发人员] [重复]

http://localhost:4200' 已被 CORS 策略阻止:对预检请求的响应未通过

AspNetCore 上 localhost 的 CORS 策略阻止

如何解决这个“http://localhost:8080”已被 CORS 策略阻止:对预检请求的响应未通过 vueJS 中的访问控制?

来自除 localhost 之外的每个来源的 CORS 策略阻止的对外部 API 的 HTTP 请求