OAuth协 议是现在众多网站提供API服务所选择的认证方式,是由Blaine Cook、Chris Messina、Larry Halff 及David Recordon共同发起,目的是为API服务提供一个安全、统一和开放的标准。众多知名的互联网公司选择了OAuth协议,如:Twitter、 Google和MySpace等;或者采用类似的认证方式,如flickr等。
Twitter.com的API在初期使用了Basic Auth的认证方 式,第三方应用只要把用户名和密码进行BASE64加密,加入到HTTP的Header中就可以使用访问受限资源的API。随着用户和第三方应用越来越 多,把用户名和密码交给第三方应用的方式越来越不安全;如果修改了密码,要在众多的第三方程序间同步密码也变得非常麻烦。最终Twitter的开发团队终 于下决心采用OAuth协议对第三方应用进行授权,用户可以随时在设置里取消授权,就算修改了密码也不必为修改授权应用的密码操心。因为OAuth协议的 安全性和可靠性,在当今流行的网络服务提供商中绝大多数选择了它。
Google也是OAuth的支持者,同时Google的DeWitt Clinton也为OAuth开发做出了巨大的贡献。我们用Google的OAuth Diagram来解释一下OAuth协议的流程。

Web Application是指我们开发的第三方应用(在下面的讲解中我们假设开发了一个访问Google日历的Flash Application),Google Account Authentication指Google的认证服务(这里可以简单的理解为是OAuth认证服务器),Google Service Access指Google提供的API服务(下面的讲解中用Google Calendar Service来替代)。当用户使用我们假设的Flash应用访问Google日历时,需要通过OAuth协议来进行授权:
首先Flash应用会访问Google OAuth认证服务,获取一个Request Token。
从Google OAuth认证服务返回一个未授权的Request Token和对应的Request Token Secret。
Flash应用继续访问Google OAuth认证服务,要求对未授权的Request Token进行授权。
如果用户已经登录了Google,会被重定向到一个请求授权页面。
用户对应用进行授权。
从Google OAuth认证服务返回已授权的Request Token和对应的Request Token Secret。
用已授权的Request Token和对应的Request Token Secret在Google OAuth服务换取Access Token。
从Google OAuth认证服务返回Access Token和对应的Access Token Secret。
使用Access Token和对应的Access Token Secret访问Google Calendar服务。
从Google Calendar返回用户的日历数据。
在Twitter的众第三方多应用中,AIR类占了很大比例。其中最知名的就是Twhirl了,可惜的是它目前还不支持OAuth认证。要想为Twhirl加入OAuth其实很容易,看完下面的例子你也可以轻松做到。
下面选择豆瓣的API为例,说明如何使用ActionScript 3开发基于OAuth认证的程序。示例程序可以在Google Code找到,在那里还有其它语言的OAuth例子。程序使用了一个OAuth的ActionScript 3类库,地址是 http://code.google.com/p/oauth-as3/,由于在OAuth的认证过程中需要HMAC-SHA1加密,所以程序还导入了一个加密功能的ActionScript 3类库,地址是 http://code.google.com/p/as3crypto/ 。
首先要在豆瓣注册一个应用,会得到豆瓣分配的Key和Secret Key。代码里面先把Key、Secret Key和豆瓣的OAuth Service地址定义为常量。
private static var DOUBAN_KEY : String = "xxxxxxxxxxxx";
private static var DOUBAN_SECRET_KEY : String = "xxxxxxxxx";
private static var DOUBAN_REQUEST : String =
"http://www.douban.com/service/auth/request_token";
private static var DOUBAN_AUTHORIZE : String =
"http://www.douban.com/service/auth/authorize";
private static var DOUBAN_ACCESS_TOKEN : String =
"http://www.douban.com/service/auth/access_token";
然后参照上图 流程1 编写一个获取Request Token访问地址的函数。
/**
* 生成获取Request Token的URL
*/
private function generalDoubanRequestTokenURL() : String
{
var oauth : OAuthRequest = new OAuthRequest("GET", DOUBAN_REQUEST);
oauth.consumer = new OAuthConsumer(DOUBAN_KEY, DOUBAN_SECRET_KEY);
return oauth.buildRequest(new OAuthSignatureMethod_HMAC_SHA1(),
OAuthRequest.RESULT_TYPE_URL_STRING);
}
调用这个函数会生成一个URL地址,把这个地址复制到浏览器里进行访问,会在页面中看到如下的显示:
oauth_token=abcde&oauth_token_secret=fghil
这两个参数的值就是未授权的Request Token和Request Token Secret。根据 流程3 对Request Token的进行授权的访问地址是
http://www.douban.com/service/auth/authorize?oauth_token=abcde
在浏览器里面输入这个地址后,就会进入到豆瓣的授权页面,如果用户还没有登录会先重定向到登录页面。
用户对应用进行授权后,需要根据 流程7 换取Access Token。
下面编写了一个函数生成换取Access Token访问地址的函数。
/**
* 生成换取Access Token使用的URL。
*/
private function generalDoubanAccessTokenURL() : String
{
var oauth : OAuthRequest = new OAuthRequest("GET", DOUBAN_ACCESS_TOKEN);
oauth.consumer = new OAuthConsumer(DOUBAN_KEY, DOUBAN_SECRET_KEY);
oauth.token = new OAuthToken('abcde', 'fghil');
return oauth.buildRequest(new OAuthSignatureMethod_HMAC_SHA1(),
OAuthRequest.RESULT_TYPE_URL_STRING);
}
将上面函数生成的地址复制到浏览器后访问,会在页面中看到如下的显示:
oauth_token=abcdww&oauth_token_secret=daseccs
这次得到的就是访问受限资源的Access Token和Access Token Secret了,使用这两个参数就可以生成访问豆瓣受限资源的URL了。
/**
* General Access douban.com's resource url
*/
private function generalPostURL(res:String, params:Object = null):String
{
var oauth : OAuthRequest = new OAuthRequest('POST', res);
oauth.consumer = new OAuthConsumer(DOUBAN_KEY, DOUBAN_SECRET_KEY);
oauth.token = new OAuthToken(‘abcdww’, ‘daseccs’);
return oauth.buildRequest(new OAuthSignatureMethod_HMAC_SHA1(),
OAuthRequest.RESULT_TYPE_URL_STRING);
}
访问的受限资源范围是根据授权用户的权限所限定的,授权用户无权访问的数据,第三方应用也无法访问。
上面的代码中,OAuth的ActionScript 3类库帮助我们封装了很多细节,很容易地实现了OAuth协议的授权。把其中豆瓣OAuth服务地址替换成Twitter OAuth服务地址,就可以生成访问Twitter的OAuth程序。这些代码很容易运用到Flex/AIR的程序里,开发类似twhirl这样的第三方应用也变得简单了。