跨源资源共享(CORS)- Facebook - 护照

10

我正在尝试在我的Nodejs / Angular / Express / Passport应用程序中通过Facebook实现OAUTH登录,但我遇到了困难。

我仍然遇到CORS错误:

XMLHttpRequest已被CORS策略阻止:所请求的资源上没有'Access-Control-Allow-Origin'标头。因此,不允许从来源 'https://www.xxxxxx.net' 访问。

尽管我已经将其添加到我的EXPRESS ROUTER中:

router.all('/*', function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');

    if ('OPTIONS' === req.method) {
      res.send(200);
    }
    else {
      next();
    }
});

在开发者控制台中,我可以看到“oauth/facebook”的GET调用的标头添加了“Access-Control-Allow-Origin”等内容。

在回调函数中没有“Access-Control-Allow-Origin”等内容 - 这样做是否正确?

router.get('/oauth/facebook/',passport.authenticate('facebook',{
      failureRedirect: '/info',
      scope:['email']
  }));

router.get('/oauth/facebook/callback/', passport.authenticate('facebook',{
      failureRedirect: '/info',
      successRedirect: '/',
      scope:['email']
  }),
  function(req,res){
    if(req.user){
      return res.json({token: req.user.generateJWT()});
    } else {
      return res.status(400).json({message:"Not found"});
    }
});

我认为访问令牌是通过头部Authorization发送的;因此,您还应在头部中提供它:res.header('Access-Control-Allow-Headers', 'Authorization, Content-Type'); 通常情况下,为了成功请求,请始终考虑提供这些头部信息:res.header('Access-Control-Allow-Headers', 'Authorization, Origin, X-Requested-With, Content-Type, Accept'); - dNitro
谢谢你的回答 - 但还是出现了相同的错误 :/ - fdddk23
你不能通过 AJAX 加载 FB 登录对话框。你需要直接在顶层窗口实例中调用它(因为用户需要通过地址栏验证他们确实正在登录 Facebook,而不是某个钓鱼网站)。 - CBroe
但是我需要从服务器端调用它,因为我还需要生成JWT以进行登录授权。 - fdddk23
2个回答

11

我在这个设置中遇到了多次失败,这些失败最终导致了这次失败。

首先,您需要使用href调用链接“/oauth/facebook/”:

<a href="/oauth/facebook/" class="btn btn-primary"><span class="fa fa-facebook"></span> Login with Facebook</a>

这确保了Angular不处理此请求。

在服务器端,它调用此路由: router.get('/oauth/facebook/',passport.authenticate('facebook',{ failureRedirect: '/#!/home', scope:['email'] }));

其中包含回调函数:

router.get('/oauth/facebook/callback/', passport.authenticate('facebook',{
      failureRedirect: '/#!/info',
      scope:['email']
  }),
  function(req,res){
    if(req.user){
      return res.redirect(303, '/#!/fb/' +req.user.generateJWT());
    } else {
      return res.status(400).json({message:"Not found"});
    }
});
在我的情况下,我还需要返回一个登录令牌:您需要自己处理响应并将调用重定向到 Angular 端的自己的“FB”路由,该路由基本上只是将我的身份验证密钥传递给 Angular 并登录用户。

1
你如何在前端“自己处理”响应? - Matt
我尝试了那种方法,但是Vue的路由会获取URL并将我发送到空白页面,因为没有指定处理它的路径。 - Wayne Smallman
非常感谢。对我来说,使用href而不是API调用是解决方案。 - SleeplessFox

1
跨域资源共享(CORS)机制为Web服务器提供了跨域访问控制,从而实现安全的跨域数据传输。 index.js:(服务器端)
const cors = require('cors');
..
..
app.use(cors());

了解如何使用跨域资源共享(CORS)的更多信息:npm cors


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接