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

时间:2015-08-17 19:36:52

标签: 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'}),
    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()?

1 个答案:

答案 0 :(得分:2)

当然可以。
这是我的解决方案:使用JS和Nodejs作为后端 主要技能是:window.postMessage
主要流程是:
 1.客户询问注册页面,服务器响应  2.注册页面触发oauth进程,它将使用" window.open(" http://your_server/oauth_page")"
 3. oauth_page做了几件事

   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.
 

4.注册页面会收到结果!

它看起来很长,但代码很简单。 这是我的注册页面代码

doctype html
html
    head
        title= title
    body
        h1= title
        p Welcome to #{title}
        button(id="github-oauth" data-oauth-server-url="github") Sign up by Github
        button(id="google-oauth" data-oauth-server-url="google") Sign up by Google
        button(id="facebook-oauth" data-oauth-server-url="facebook") Sign up by Facebook
        script(type="text/javascript").
            window.onload = function() {
                var oauth_page;
                var oauth_server_url;
                function createOauthButtonListner(elem) {
                    elem.addEventListener("click", function () {
                        oauth_page = window.open("http://localhost:3000/oauth_page");
                        //determine which button is triggered.
                        oauth_server_url = elem.getAttribute("data-oauth-server-url");
                        console.log(oauth_server_url);
                    })
                };
                window.addEventListener('message', function (e) {
                    if (e.data == "ready") {
                        // send oauth url
                        oauth_page.postMessage(oauth_server_url, "http://localhost:3000");
                    } else {
                        // return oauth resut
                        console.log(e.data);
                    }
                }, false);
                createOauthButtonListner(document.getElementById("github-oauth"));
                createOauthButtonListner(document.getElementById("google-oauth"));
                createOauthButtonListner(document.getElementById("facebook-oauth"));
            }

这是我的Oauth_page

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)

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

在注册页面中,打开控制台,您可以看到结果 随意问我问题;)
我在一周内为此工作 希望它可以帮到你。