Javascript Angularjs oauth弹出窗口,等待JSON响应
我需要发出一个oauth请求,我想在一个新窗口中启动该请求 我知道我可以像这样打开窗户: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'})
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});
});
});
});