纯 JavaScript 实现的 OAuth 认证

标签: IT技术 Javascript oAuth | 发表时间:2013-05-03 21:05 | 作者:童海波
出处:http://blog.jobbole.com

英文原文: JavaScript oAuth 编译: oschina

引言

现在,很多的应用程序都在使用HTML和JavaScript, 这是一个非常明智的选择,让你跟上目前的趋势. 一些主要实体工具因为客户端验证和授权等原因提供了API. 当前网站对于验证的一个广受欢迎的功能是”单点登录”. 这让用户可以通过其它一些社交媒体网站上的身份认证直接登录你的网站. 这篇文章介绍用纯JavaScript通过一个简单的方法让你从三个身份认证提供者上登录到你的网站.

背景

为了使用身份认证提供者的API, 你要在他们的网站上创建一个应用,完成后它将提供一个API key让你使用.

使用这些代码

如果你不打算长篇阅读,你可以去直接下载源代码文件然后随便你怎么使用/修改。

首先,我们包含一些文件在我们的HTML页面的头部。

<!--Register Jquery-->
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.1.0.js"></script>
<!--Register Google Api-->
<script src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>

最近的时间,Twitter已经废弃使用可能会导致开发者变得畏畏缩缩的单点客户端认证。然而,感谢YUI(由Yahoo!提供的API)我们能够使用Javascript这样去模拟一个服务端请求到Twitter。所以我们也可以把YUI的库包含在头部。

<!--Register YUI Api-->
<script type="text/javascript" 
  src="http://yui.yahooapis.com/3.3.0/build/yui/yui-min.js"></script>

我们现在创建DOM元素来触发请求。这些元素可以是你的任意选择。

<div id="fbLogin" onclick="">Facebook</div>
<div id="twitterlogin">Twitter</div>
<div id="googlelogin">Google</div>

现在我们看下脚本。我们从Facebook的登陆开始。

Facebook

我们要创建的第一个函数用来向 Facebook oAuth API 发送初始化请,函数将发送客户端 ID(由你的Facebook 应用给出),重定向 URL (必须同你注册应用时填写的一样),还有请求类型(此处是访问令牌)。访问令牌是用户验证所必须的,并也会用来访问 Facebook 的图形 API,以及获取用户个人信息。

var appID = <YOUR CLIENT ID>;
 
function fbLogin() {
    var path = 'https://www.facebook.com/dialog/oauth?';
    var queryParams = ['client_id=' + appID,
    'redirect_uri=' + window.location,
    'response_type=token'];
    var query = queryParams.join('&');
    var url = path + query;
    window.location.replace(url);
}

相应将是一个附加形如 “#access_token=…….” 的哈希字符串的访问令牌的到你网站的重定向。要使用访问令牌,我们现在需要一个检查 URL 中访问令牌的函数。同时此函数也将对 Facebook 图形 API 发送一个带有访问令牌和一个以参数形势接受用户信息的回调函数的请求。

function checkFbHashLogin() {
 
    if (window.location.hash.length > 3) {
        var hash = window.location.hash.substring(1);
        if(hash.split('=')[0] == 'access_token')
        {
            var path = "https://graph.facebook.com/me?";
            var queryParams = [hash, 'callback=displayUser'];
            var query = queryParams.join('&');
            var url = path + query;
 
            //use jsonp to call the graph
            var script = document.createElement('script');
            script.src = url;
            document.body.appendChild(script);
        }
       
    }
}

第三步,我们的回调函数会将用户信息转化为我们可见的形势。

function displayUser(user) {
    setTimeout(function () { }, 1000);
    if (user.id != null && user.id != "undefined") {
       //Do Stuff
       //You have access to user id, name, username, gender etc.
       //For more info visit https://developers.facebook.com/docs/
       //                      reference/login/public-profile-and-friend-list   
    }
    else {
        alert('user error');
    }
}

最后,我们需要一个函数调用的触发器,且我们也需要一个在页面加载的时候检查哈希字符串的函数。

$(function () {
 
    checkFbHashLogin();
 
    $('#fbLogin').click(function () {
        fbLogin();
    });
})

现在我们已完成了Facebook的身份验证。

Google

首先,我将给出一个带有解释运作的注释的函数。如前所述,我们需要谷歌的客户端ID,我们的应用必须使用 API 密钥。

var clientId = <YOUR CLIENT ID>;
var apiKey = <YOUR API KEY>;
var scopes = 'https://www.googleapis.com/auth/plus.me';  
 
 
// Our first function is used to set the api key and
// is run once the google api is loaded in the page header. 
function handleClientLoad() {
    gapi.client.setApiKey(apiKey);
}
 
//Gets the result after the authorization and if successful,
//it makes the api call to get the  //user's information.
function handleAuthResult(authResult) {
 
    if (authResult && !authResult.error) {
        makeApiCall();
    } 
}
  
//Make api call on button click to authorize client
function handleAuthClick(event) { gapi.auth.authorize({ client_id: clientId, 
            scope: scopes, immediate: false }, handleAuthResult);
 
    return false;
}
 
// Load the API and make an API call.  Display the results on the screen.
function makeApiCall() {
    gapi.client.load('plus', 'v1', function () {
        var request = gapi.client.plus.people.get({
            'userId': 'me'
        });
 
        request.execute(function (resp) {
        //Do Stuff
         //You have access to user id, name, display name, gender, emails, etc.
        //For more info visit https://developers.google.com/+/api/latest/people#resource 

        });
    });
}
 
$(function () {
    var authorizeButton = document.getElementById('googlelogin');
    authorizeButton.onclick = handleAuthClick;
})

这样就完成了谷歌的认证。

Twitter

正如之前所说,Twitter API 并不允许纯粹的客户端验证。因此需要使用 YUI 库。此库使用雅虎查询语言(YQL)制定对Twitter API 的服务器端请求。

例如,应用中可能使用的一条 YQL 如下:

select * from twitter.oauth.requesttoken where oauth_callback="<YOUR WEBSITE URL>";

你可以看到,select 语句同其它查询语言的 select 语句一样。select 语句的条件参数(oauth_callback)是你 Twitter 应用所注册的 URL。由于我们选择 URL 匹配,我们并不需要客户端ID。由于我们使用 JavaScript,我们可以使用 window.location 获取当前 URL 用于查询(在代码中已处理)。本质上,我们无需关注 YUI 和 YQL。因此,让我们看看 YUI 库的实现,以及它是如何调用 Twitter API 的。

首先是初始化 YUI 对象。使用此对象,我们将设定所用的模块以及它们的地址。在这里将使用 Twitter 和 YQL 模块。

YUI({
    combine: false,
    filter: "raw",
    debug: false,
    modules: {
        
        'Twitter': {
           fullpath: 'js/twitter.js'
        },
        'myYQL': {
            fullpath: 'js/yql.js',
            requires: ['jsonp', 'jsonp-url']
        }
    }
})

下一步,我们将告知 YUI库我们将使用资源库中的哪个组件,并提供回调函数。我们通过调用 YUI 的 “use” 函数完成此操作,只需添加到初始化后的 YUI 对象之后。

YUI({
    ...
}).use('Twitter', 'gallery-storage-lite', 'myYQL', 'node', "event", function (Y) {});

回调函数将在 YUI 库初始化完成并选定组件之后调用,我们将所有处理 Twitter API 用户验证的代码放置其中。首先要做的是获取触发Twitter 用户验证的元素,并将点击事件绑定的到一个函数上。这个函数将进行第一次 API 调用,获取 oAuth 请求令牌和密钥。这些将在一个查询字符串中传递到 Twitter 用户验证 API,oAuth 令牌验证将以同样的方式返回

var twtBtn = Y.one('#twitterlogin');
 
twtBtn.on('click', function (e) {
    Y.Twitter.call({ type: "request_token" }, function (tokens) {
        Y.log("step 1");
        Y.log(tokens);
        Y.StorageLite.setItem('oauth_token', tokens.oauth_token);
        Y.StorageLite.setItem('oauth_token_secret', tokens.oauth_token_secret);
        window.setTimeout(function () {
            window.location = "https://twitter.com/oauth/authenticate?oauth_token=" + 
              tokens.oauth_token + "&oauth_token_secret=" + tokens.oauth_token_secret;
        }, 10);
    });
});

下面几步将结合嵌套的调用和响应,知道我们获得最终的响应。首先我们将检查查询字符串以获取oAuth 令牌验证。接着令牌和验证将被传递给 YUI Twitter调用以获取访问令牌。最后,访问令牌将被发送到一个调用,以索取用户信息。

if (getQueryStringParameter('oauth_token')) {
 
    Y.StorageLite.setItem('oauth_token', getQueryStringParameter('oauth_token'));
    Y.StorageLite.setItem('oauth_verifier', getQueryStringParameter('oauth_verifier'));

    Y.Twitter.config({
        oauth_token: getQueryStringParameter('oauth_token'),
        oauth_token_secret: getQueryStringParameter('oauth_token_secret')
    });

    Y.Twitter.call({ type: "access_token" }, function (tokens) {
        Y.Twitter.config({
            oauth_token: tokens.oauth_token,
            oauth_token_secret: tokens.oauth_token_secret
        });

        Y.Twitter.call({ type: "credentials" }, function (user) {
            Y.Twitter.config({
                screen_name: user.screen_name,
                user_id: user.id
            });

            //Do Stuff
        //You have access to user id, name, screenname, description, etc.
        //For more info visit https://dev.twitter.com/docs/api/1.1/get/account/verify_credentials 
       });
    });
}

这将完成 Twitter 认证组件的所有请求。

//Supporting function to parse the query string 
function getQueryStringParameter(key, queryString) {
    
    var queryString = queryString || window.location.href;
    key = key.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
    var regex = new RegExp("[\\?&]" + key + "=([^&#]*)");
    var qs = regex.exec(queryString);
    if (qs)
        return qs[1];
    else
        return false;
}

两点

现今,单点登录的使用率正迅速增长,很多大型网站,如雅虎和Hotmail都允许用户使用单点登录进行验证。例如,在配置Google API时,你可以将其它供应商同你的 Google API 密钥绑定。值得注意的是,所有请求都将使用各个验证提供者应用所登记域名,同时你将需要使用正确的域名和URL网址。因此,应用在你的 Localhost 将无法正常工作。

相关文章

纯 JavaScript 实现的 OAuth 认证,首发于 博客 - 伯乐在线

相关 [javascript oauth 认证] 推荐:

纯 JavaScript 实现的 OAuth 认证

- - 博客 - 伯乐在线
英文原文: JavaScript oAuth 编译: oschina. 现在,很多的应用程序都在使用HTML和JavaScript, 这是一个非常明智的选择,让你跟上目前的趋势. 一些主要实体工具因为客户端验证和授权等原因提供了API. 当前网站对于验证的一个广受欢迎的功能是”单点登录”. 这让用户可以通过其它一些社交媒体网站上的身份认证直接登录你的网站.

oauth 认证心得

- 非狐外传 - python.cn(jobs, news)
OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准. 简易来说,就是我们可以在某一个第三方服务器,如:新浪,豆瓣,在用户授权,并且不透漏密码等信息给我们的条件下,访问和修改用户的资源. oauth的项目主页为:http://oauth.net/ ,现在国内很多网站的开放平台都采用了Oauth方式来进行授权.

OAuth的改变

- lyxint - 火丁笔记
去年我写过一篇《OAuth那些事儿》,对OAuth做了一些简单扼要的介绍,今天我打算写一些细节,以阐明OAuth如何从1.0改变成1.0a,继而改变成2.0的. 在OAuth诞生前,Web安全方面的标准协议只有OpenID,不过它关注的是验证,即WHO的问题,而不是授权,即WHAT的问题. 好在FlickrAuth和GoogleAuthSub等私有协议在授权方面做了不少有益的尝试,从而为OAuth的诞生奠定了基础.

理解OAuth 2.0

- - 阮一峰的网络日志
OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为 RFC 6749. 为了理解OAuth的适用场合,让我举一个假设的例子. 有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来.

OAuth学习笔记

- 宋大妈 - FeedzShare
来自: 标点符 - FeedzShare  . 发布时间:2011年08月29日,  已有 2 人推荐. OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据.

OAuth 2.0 工作流程

- - 企业架构 - ITeye博客
原文链接:http://www-01.ibm.com/support/knowledgecenter/SSELE6_8.0.0.3/com.ibm.ammob.doc_8.0.0.3/config/concept/con_oauth20_workflow.html%23con_oauth20_workflow?lang=zh.

GitHub - casinthecloud/cas-pac4j-oauth-demo: Demo webapps to test CAS/OAuth/OpenID/SAML client support and OAuth server support in CAS version >= 4.0.0

- -

基于PECL OAuth打造微博应用

- lostsnow - 火丁笔记
最近,国内主要门户网站相继开放了微博平台,对开发者而言这无疑是个利好消息,不过在实际使用中却发现平台质量良莠不齐,有很多不完善的地方,就拿PHP版SDK来说吧,多半都是用TwitterOAuth改的,一旦多平台集成,很容易出现命名冲突之类的问题. 既然官方SDK不给力,那我们只能发扬自力更生的革命精神了.

PHP实现Google Oauth的登录系统

- - 极客521 | 极客521
本文讲述的是如何为你的PHP项目实现Google的Oauth系统. 这个示例PHP脚本非常快,对增加你的PHP项目注册当然是很有帮助的. 在这之前,我们已经覆盖了包含Facebook、Twitter、Google plus以及Instagram的Oauth登录系统示例. 很遗憾之前我遗漏掉了Google的Oauth登录系统.