Node.js passport.js,在弹出窗口中进行身份验证后,关闭它并重定向父窗口

Node.js passport.js,在弹出窗口中进行身份验证后,关闭它并重定向父窗口,node.js,facebook,popup,passport.js,Node.js,Facebook,Popup,Passport.js,在我的node.js express应用程序中,我使用集成了Facebook身份验证。我可以在弹出窗口中打开Facebook登录页面,然后进行登录。在此阶段,重定向将在弹出窗口中进行。但是我需要关闭弹出窗口并在父窗口中进行重定向(即父窗口将重定向)。我将在这里粘贴完整的代码,尽管我认为主要问题在于模板文件(.ejs)。 而我也找不到任何解决类似问题的办法 // Passport session setup. passport.serializeUser(function(user, done)

在我的node.js express应用程序中,我使用集成了Facebook身份验证。我可以在弹出窗口中打开Facebook登录页面,然后进行登录。在此阶段,重定向将在弹出窗口中进行。但是我需要关闭弹出窗口并在父窗口中进行重定向(即父窗口将重定向)。我将在这里粘贴完整的代码,尽管我认为主要问题在于模板文件(.ejs)。

而我也找不到任何解决类似问题的办法

// Passport session setup.
passport.serializeUser(function(user, done) {
  done(null, user);
});

passport.deserializeUser(function(obj, done) {
  done(null, obj);
});


// Use the FacebookStrategy within Passport.
passport.use(new FacebookStrategy({
    clientID: config.facebook_api_key,
    clientSecret:config.facebook_api_secret ,
    callbackURL: config.callback_url
  },

  function(accessToken, refreshToken, profile, done) {

    console.log(" id = "+profile.id);

    process.nextTick(function () {
      //Check whether the User exists or not using profile.id
      //Further DB code.
      profile.user_id="00000444000555";
      return done(null, profile);
    });

  }
));

app.set('views', __dirname + '/views');

app.set('view engine', 'ejs');
//app.set('view engine', 'jade');
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({ secret: 'keyboard cat', key: 'sid'}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/public'));

//Router code
app.get('/', function(req, res){
  res.render('index', { user: req.user });
});

app.get('/account', ensureAuthenticated, function(req, res){

    console.log(req.user);
  res.render('account', { user: req.user });
});

//Passport Router
app.get('/auth/facebook', passport.authenticate('facebook'));
app.get('/auth/facebook/callback',

passport.authenticate('facebook', {
       successRedirect : '/',
       failureRedirect: '/login'
  }),

   function(req, res) {
    res.redirect('/');

  });

app.get('/logout', function(req, res){
  req.logout();
   res.redirect('/');
});

function ensureAuthenticated(req, res, next) {
     if (req.isAuthenticated()) { return next(); }
  res.redirect('/login')
}
app.listen(8000);
模板文件为:

<script type="text/javascript">
    if (window.location.hash && window.location.hash == '#_=_') {
        if (window.history && history.pushState) {
            window.history.pushState("", document.title, window.location.pathname);
        } else {
            // Prevent scrolling by storing the page's current scroll offset
            var scroll = {
                top: document.body.scrollTop,
                left: document.body.scrollLeft
            };
            window.location.hash = '';
            // Restore the scroll offset, should be flicker free
            document.body.scrollTop = scroll.top;
            document.body.scrollLeft = scroll.left;
        }
    }
</script>

<% if (!user) { %>

  <div style="width:500px;height:180px;">
    <h2 style="font-size:40px;">Welcome! Please log in.</h2>
    <a href="javascript:void(0)" onclick=" window.open('/auth/facebook','',' scrollbars=yes,menubar=no,width=500, resizable=yes,toolbar=no,location=no,status=no')"><img src="fb-login.jpg" width="151" height="24"></a>
    </div>

<% } else { %>

<script type="text/javascript">

    window.parent.location.href ="/";
    window.close();
</script>
    <h2>Hello, <%= user.displayName %>.</h2>
<% } %>

if(window.location.hash&&window.location.hash='#{
if(window.history&&history.pushState){
window.history.pushState(“”,document.title,window.location.pathname);
}否则{
//通过存储页面的当前滚动偏移量来防止滚动
变量滚动={
top:document.body.scrollTop,
左:document.body.scrollLeft
};
window.location.hash='';
//恢复滚动偏移,应无闪烁
document.body.scrollTop=scroll.top;
document.body.scrollLeft=scroll.left;
}
}
欢迎请登录。
window.parent.location.href=“/”;
window.close();
你好

我上面的评论可能缺少完整的答案,所以这里是我在我的网站上所做的完整解决方案

在我的节点后端,我创建了一个路由,在成功进行身份验证后,它基本上会路由到一个名为after-auth.html的特殊页面

app.get('/auth/twitter/callback',
  auth.passport.authenticate('twitter', { failureRedirect: '/failedLogin.html' }),
  function(req, res) {
    res.redirect('/after-auth.html');
});
我的after-auth.html页面只是有一个javascript,它将焦点放回父页面,并像这样关闭自己

<script type="text/javascript">
    if (window.opener) {
        window.opener.focus();

      if(window.opener.loginCallBack) {
        window.opener.loginCallBack();
      }
    }
    window.close();
</script>  

我们自己也在努力解决这个问题,最后编写了一个简单的javascript插件来帮助我们解决这个问题

在客户端上使用它的过程如下:

<button id="button">Facebook Login</button>
<script>
document.getElementById("button").onclick = function () {
    popupTools.popup('/popup-url', "Facebook Connect", {}, function (err, user) {
        if (err) {
            alert(err.message);
        } else {
            // save the returned user in localStorage/cookie
        }
    })
</script>

希望人们会觉得这很有用。

最简单的解决方案是:

res.send('window.close()');

这可能有帮助吗?不是同一堆,但你可以借用他们的idea@kane非常准确,但他们正在使用angular将消息发送回父窗口。。。我现在想知道我怎么能做到这一点没有角度。。。似乎打开一个套接字并向自己发送消息是可行的,但似乎有些过分了。是的,我昨天发布了我的评论后才发现,我可以从模式窗口访问家长,现在我正在实现与您在这里描述的相同的事情,但据我所知,IE有时会告诉windows.opener由于某些IE策略而未定义,这是一个问题,但IE支持showModalDialog,它被Chrome贬低,但可以作为IE的window.open()的替代品。谢谢你的回答)超级!没有麻烦。只是一个简单的问题。它适用于所有浏览器吗?如果我想在弹出窗口中显示fb和google等选项并发送请求,该怎么办。我试过了,但回复是errHahaha很高兴你滚动到了最底部“\_(ツ)_/''哦,简洁优雅。
<button id="button">Facebook Login</button>
<script>
document.getElementById("button").onclick = function () {
    popupTools.popup('/popup-url', "Facebook Connect", {}, function (err, user) {
        if (err) {
            alert(err.message);
        } else {
            // save the returned user in localStorage/cookie
        }
    })
</script>
passport.use(new FacebookStrategy({
    clientID: process.env.FACEBOOK_ID,
    clientSecret: process.env.FACEBOOK_SECRET,
    callbackURL: '/calback-url',
}, function (accessToken, refreshToken, profile, done) {
    // process facebook profile into user
}));

app.post('/popup-url', passport.authenticate('facebook'))
app.get('/callback-url', 
    passport.authenticate('facebook'),
    function (req, res) {
        res.end(popupTools.popupResponse(req.user))
    }
);