Javascript Angularjs oauth弹出窗口,等待JSON响应

Javascript Angularjs oauth弹出窗口,等待JSON响应,javascript,json,angularjs,oauth-2.0,passport.js,Javascript,Json,Angularjs,Oauth 2.0,Passport.js,我需要发出一个oauth请求,我想在一个新窗口中启动该请求 我知道我可以像这样打开窗户: var authWindow = $window.open("/auth/google/signin", ""); 我的服务器将处理回调并使用JSON进行响应: app.get('/auth/google/signin', passport.authenticate('google', { scope: 'https://www.googleapis.com/auth/plus.login'})

我需要发出一个oauth请求,我想在一个新窗口中启动该请求

我知道我可以像这样打开窗户:

var authWindow = $window.open("/auth/google/signin", "");
我的服务器将处理回调并使用JSON进行响应:

 app.get('/auth/google/signin',
    passport.authenticate('google', { scope: 'https://www.googleapis.com/auth/plus.login'}),
    function(req, res, next) {
      // The request will be redirected to Google for authentication, so this
      // function will not be called.
    }
  );

app.get('/auth/google/callback',
    function(req, res, next) {
      passport.authenticate('google', function(err, user, info) {
        console.log('google authenticate callback');

        // do some stuff, then send back token and user...

        res.json({
          token:token,
          user: user
        });

      })(req, res, next);
    }
  );
我需要等待,直到弹出窗口被重定向到/auth/google/callback,并且JSON数据从服务器返回

如何等待服务器的重定向和JSON响应

一旦我等待并获得了JSON数据,什么是返回数据的最佳方式?回拨?postMessage()?

当然可以。
以下是我的解决方案:使用JS和Nodejs作为后端。
主要技能是:window.postMessage
主要流程是:
1.客户端请求注册页面,服务器响应。
2.注册页面触发oauth进程,它将使用“window.open(“”)”
3.oauth_页面可以做几件事

a. Check the state(default/success) b. if in dedault state, using window.opener.postMessages('ready','*') to tell main window(signup page) I am ready. Then signup page would listen messages and return which oauth url assigned. Because I have several oauth methods in one page(Github/Google+/Facebook) c. The oauth_page would send XHR request to server. d. server would send redirect_url back to oauth_page. e. oauth_page would use "window.location_url" to redirect. Now you can see the authorization page. f.The authorization result would send back to server. g.server would run exchange code, take access_token and get info you wanted.... I supposed you know this process.(passport library do.) h.return the oauth_page to the same child window! The magic is that window.opener is still the signup page,so you can send result back as before. 这是我的Oauth_页面

doctype html
html
    head
        title= "Oauth Page"
    body
        p Welcome to Oauth page
        p#status #{status}
        p#content #{content}
        script(type="text/javascript").
            window.onload = function(){
                // return msg to host window
                if (document.getElementById('status').innerHTML == 'success') {
                    window.opener.postMessage(document.getElementById('content').innerHTML, '*');
                    window.close();
                }else if(document.getElementById('status').innerHTML == 'default'){
                    window.opener.postMessage('ready', '*');
                }
                // redirect to oauth page
                window.addEventListener('message', function (e) {
                    console.log(window);
                    if (e.origin != "http://localhost:3000") {
                        console.log("error");
                        return;
                    } else {
                        if (document.getElementById('status').innerHTML == 'default') {
                            var xhttp = new XMLHttpRequest();
                            xhttp.open("GET", e.data, true);
                            xhttp.send();
                            xhttp.onreadystatechange = function () {
                                if (xhttp.readyState == 4 && xhttp.status == 200) {
                                    window.location.href = JSON.parse(xhttp.responseText).redirect_url;
                                }
                            };
                        }
                    }
                }, false);
            };
我的服务器端代码(相当混乱:p)

在注册页面中,打开控制台,您可以看到结果。
请随便问我问题;)
我为此工作了一周。

希望它能帮助你

您不能打开“隐藏窗口”,而是创建一个隐藏的iframe并将结果存储在cookie中。很抱歉,不需要隐藏窗口,因为用户需要输入凭据。但是,我是否应该能够在宣誓完成后从子窗口获取JSON数据而不使用Cookie?不,您需要使用Cookie传输数据。大多数开发人员创建一组3个或更多MD5哈希字符串,以匹配数据库中的字段。使用cookies传输3个哈希值。通过将SSL添加到用于oAuth的页面,您可以更进一步。
doctype html
html
    head
        title= "Oauth Page"
    body
        p Welcome to Oauth page
        p#status #{status}
        p#content #{content}
        script(type="text/javascript").
            window.onload = function(){
                // return msg to host window
                if (document.getElementById('status').innerHTML == 'success') {
                    window.opener.postMessage(document.getElementById('content').innerHTML, '*');
                    window.close();
                }else if(document.getElementById('status').innerHTML == 'default'){
                    window.opener.postMessage('ready', '*');
                }
                // redirect to oauth page
                window.addEventListener('message', function (e) {
                    console.log(window);
                    if (e.origin != "http://localhost:3000") {
                        console.log("error");
                        return;
                    } else {
                        if (document.getElementById('status').innerHTML == 'default') {
                            var xhttp = new XMLHttpRequest();
                            xhttp.open("GET", e.data, true);
                            xhttp.send();
                            xhttp.onreadystatechange = function () {
                                if (xhttp.readyState == 4 && xhttp.status == 200) {
                                    window.location.href = JSON.parse(xhttp.responseText).redirect_url;
                                }
                            };
                        }
                    }
                }, false);
            };
router.get('/oauth_page', function (req, res, next) {
    res.render('oauth', {status: 'default', content: 'none'});
})

// for github oauth
router.get('/github', function(req, res){
  var github_oauth_url = "https://github.com/login/oauth/authorize" +
      "?client_id=" + github_client_id  +
      "&scope=user" ;
  res.send(JSON.stringify({"redirect_url":github_oauth_url}));
});

router.get('/github/callback', function(req, res){
    var code = req.query.code;
    var token_option = {
        url:"https://github.com/login/oauth/access_token",
        method:"POST",
        form:{
            code: code,
            client_id: github_client_id,
            client_secret: github_secret_id
        }
    };
  request(token_option, function(err, response, body){
      if(err){
          res.send(response);
      }
      var regex = /\=([a-zA-Z0-9]+)\&([a-zA-Z])+\=([a-zA-Z0-9]+)/;
      var result = body.match(regex);
      console.log(result, body);
      var token = result[1];

      var info_option = {
          url:"https://api.github.com/user",
          method:"GET",
          headers:{
              "User-Agent": "Awesome-Octocat-App",
              "Authorization":"token "+ token
          }
      }
      request(info_option, function(err, response, body){
         if(err){
             res.send(err);
         }
          res.render('oauth', {status: 'success', content:body});
      });
  });
});