Express.js - 跨域请求被阻止

Posted

技术标签:

【中文标题】Express.js - 跨域请求被阻止【英文标题】:Express.js - Cross-Origin Request Blocked 【发布时间】:2020-01-03 02:56:09 【问题描述】:

我有一个 Node.js 服务器在 localhost 端口 3000 上运行。我还有一个在端口 8080 上运行的 Vue.js 应用程序。我已经在用 Vue.js 编写的登录表单上实现了 passportjs(Google 策略)。

但是,当我点击 Google+ 按钮时,我遇到了一个 CORS 被阻止的错误,它告诉我即使我在服务器代码中启用了 cors,我也缺少 CORS。

我已经尝试将参数更改为cors()

app.use(cors(origin: 'http://localhost:3000', credentials: true));

我也试过添加Header set Access-Control-Allow-Origin '*' 到我的apache2.conf 文件。

每次点击按钮时,我都会收到一个 HTTP 302 代码。

Node.js 文件:

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const passport = require('passport');

const app = express();

app.use(cors());

// Routes
app.use('/user', users);

// Passport strategy
passport.use(new GoogleStrategy(
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: '/user/google/redirect'
,
function(accessToken, refreshToken, profile, done) 
    User.findOrCreate( googleId: profile.id , function (err, user) 
        return done(err, user);
    );
));

// Server start
app.listen(3000, (req, res) => 
    console.log(`Listening to port 3000...\n`);
);

路由器:

// auth with google+
router.get('/google', passport.authenticate('google', 
     scope: ['https://www.googleapis.com/auth/plus.login']  
));

// callback route for google to redirect to
router.get('/google/redirect', passport.authenticate('google', 
     failureRedirect: '/login' ),
    function(req, res) 
    res.send('Done!');
);

Vue.js 文件:

<template>
    <v-card class="elevation-12" v-on:submit.prevent="login">
        <mdb-btn align-center justify-center class="btn-gplus" icon="google-plus-g" fab v-on:click="authGoogle()">Google +</mdb-btn>
    </v-card>
</template>

<script>
import axios from 'axios';
import router from '../router/router';
import  mdbBtn  from 'mdbvue';

const  URL  = require('../config');

export default 
  name: 'Login',
  methods: 
    authGoogle () 
      axios.get(`$URL/user/google`, 
      ).then(res => 
        console.log(res);
      ).catch(err => 
        console.log(err);
      )
    
  ,
  components: 
    mdbBtn
  
;
</script>

当我在浏览器中输入http://localhost:3000/user/google/ 时,Google 登录页面会成功打开,但我无法在我的代码中完成此操作。

【问题讨论】:

【参考方案1】:

跨域请求被阻止错误不是由您的服务器配置引起的,而是由 Google 的服务器配置引起的。您的服务器尝试将客户端重定向到 Google 的登录页面。出于安全原因,浏览器并不总是允许这些类型的跨源重定向(否则您总是可以通过在您自己的域上添加重定向端点页面来绕过 CSRF 保护)。要解决此问题,您可以使用指向 http://localhost:3000/user/google/ 的实际 html 链接,如下所示:

<a href="http://localhost:3000/user/google/">Google+</a>`

【讨论】:

【参考方案2】:

您可以通过中间件中的响应头添加cors头:

app.use(function(req, res, next) 
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
    next();
);

【讨论】:

我试过这个,但似乎并没有解决问题。我仍然得到同样的错误

以上是关于Express.js - 跨域请求被阻止的主要内容,如果未能解决你的问题,请参考以下文章

跨域请求被阻止 Symfony/AngularJS

socket.io 跨域请求被阻止

跨域请求被阻止原因:CORS 预检通道未成功

jQuery ajax 请求因为跨域而被阻止

AJAX 请求跨域请求被阻止错误

跨域请求被阻止