当然可以。
这是我的解决方案:使用 JS 和 Nodejs 作为后端。
主要技巧是:window.postMessage
主要流程是:
1. 客户端询问注册页面,服务器响应。
2. 注册页面触发oauth进程,会使用"window.open("http://your_server/oauth_page")"
3. oauth_page 做了几件事
一种。检查状态(默认/成功)
湾。如果处于默认状态,则使用 window.opener.postMessages('ready','*')
告诉主窗口(注册页面)我准备好了。
然后注册页面会监听消息并返回分配的 oauth url。
因为我在一页中有几个 oauth 方法(Github/Google+/Facebook)
C。 oauth_page 会将 XHR 请求发送到服务器。
d。服务器会将redirect_url 发送回oauth_page。
e. oauth_page 将使用“window.location_url”进行重定向。现在您可以看到授权页面。
f.授权结果将发送回服务器。
g.server 将运行交换代码,获取 access_token 并获取您想要的信息......我想你知道这个过程。(护照库做。)
h.将 oauth_page 返回到同一个子窗口!神奇的是 window.opener 仍然是注册页面,所以你可以像以前一样发回结果。
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});
});
});
});
在注册页面,打开控制台就可以看到结果了。
随时问我问题;)
我在一周内为此工作。
希望它可以帮助你。