豆瓣api通过OAuth允许第三方应用访问用户数据,所以OAuth认证就是我们整个project的基础了。

OAuth认证听起来挺神秘,其实挺简单的。

现在的大型网站的开放平台的认证几乎都是采用OAuth,比如facebook,twitter,新浪微博等。

豆瓣的api有对于OAuth认证的专门说明:http://www.douban.com/service/apidoc/auth

在你使用OAuth认证之前,先仔细读一读文档非常有必要,因为中间过程出现一点偏差,你就不能被认证成功,所以仔细阅读官方文档是重中之重:http://oauth.net/documentation/spec/

如果你的英文不够给力的话,可以看看这篇中文的介绍,说的很清楚:http://www.supidea.com/post/oauth.aspx

google OAuth项目已经提供了OAuth的各种语言的库:http://code.google.com/p/oauth/

我们正式使用了google OAuth中的C#库: http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs

因为OAuth已经成为了第三方开发者使用豆瓣api的一大障碍,豆瓣曾经专门举办了一次活动来讲解如何通过OAuth使用豆瓣api:http://www.douban.com/online/10012959/

这次活动的源码在google code上可以找到:http://code.google.com/p/douban-oauth-sample/,我们正式参考了http://code.google.com/p/douban-oauth-sample/source/browse/trunk/csharp/DoubanOAuthBasicSample/DoubanOAuthBasicSample/Program.cs这个文件,对我们的帮助很大,省去了很多摸索的时间

作为命令行程序我们已经测试成功了,但是当移植到windows phone上之后就出现了问题

问题的关键在于silverlight版的网络方面的api和C#的不同,silverlight的api更少,这就导致了上面的库的一些网络访问要自己改写

仔细阅读httpwebrequest的文档后,我们发现,要进行一个网络请求,至少要三个函数,因为需要使用两次异步请求(BeginGetRequestStream, BeginGetResponse)

因为我们的豆瓣app几乎每个动作都要对豆瓣服务器进行请求,如果每个请求都需要写三个函数,并且还要增加认证信息的话,实在是太麻烦,代码会变得又臭又长

这时候DRY(don’t repeat yourself)就显得尤为重要了

作为pm,我决定把网络访问这一块封装好,给大家提供统一的,简单好用的借口。

我本准备自己把那两个异步请求封装起来,后来发现已经有现成的库可用,而且很好很强大。

这个库就是restsharp:http://restsharp.org/

而且restsharp还提供了windows phone对应的dll,很是方便,原来的三个函数现在只需要一个函数几行就可以搞定

对于很多请求,豆瓣都要求有认证才可以访问,根据豆瓣的文档“进行POST、PUT、DELETE请求时,豆瓣暂时不支持使用在url中或者post form中传递OAuth参数。因此你只能选择在header中传递OAuth参数”,看来我们只能把oauth加到http header中了。

我部分我统一封装了一下:
namespace AddOAuthHeader{
    public class OAuthHeader{
        string apiKey = "your api key";
        string apiKeySecret = "your api key secret";
        string accessToken;
        string accessTokenSecret;
        string uri;
        string method;
        OAuthBase oAuth = new OAuthBase();
        IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

public OAuthHeader(string uri, string method) {
            this.uri = uri;
            this.method = method;
        }

public string getHeader(){
            string nonce = oAuth.GenerateNonce();
            string timeStamp = oAuth.GenerateTimeStamp();
            string normalizeUrl, normalizedRequestParameters;

//accessToken = settings["accessToken"].ToString();
            //accessTokenSecret = settings["accessTokenSecret"].ToString();

accessToken = "ee7ead643e6ea1a1cb7c082cbb4be4e3";
            accessTokenSecret = "545138430a2dcc9b";

string sig = oAuth.GenerateSignature(
                new Uri(uri),
                apiKey,
                apiKeySecret,
                accessToken,
                accessTokenSecret,
                method,
                timeStamp,
                nonce,
                OAuthBase.SignatureTypes.HMACSHA1,
                out normalizeUrl,
                out normalizedRequestParameters);
            sig = HttpUtility.UrlEncode(sig);

StringBuilder oauthHeader = new StringBuilder();
            oauthHeader.AppendFormat("OAuth realm=\"\", oauth_consumer_key={0}, ", apiKey);
            oauthHeader.AppendFormat("oauth_nonce={0}, ", nonce);
            oauthHeader.AppendFormat("oauth_timestamp={0}, ", timeStamp);
            oauthHeader.AppendFormat("oauth_signature_method={0}, ", "HMAC-SHA1");
            oauthHeader.AppendFormat("oauth_version={0}, ", "1.0");
            oauthHeader.AppendFormat("oauth_signature={0}, ", sig);
            oauthHeader.AppendFormat("oauth_token={0}", accessToken);

return oauthHeader.ToString();
        }
    }
}

传入一个url和一个方法(post or put or delete or get),我就给他返回一个oauth header,其他同学直接调用我的代码就好了,并不需要关心认证问题

那具体该如何来进行一个网络请求呢?

我写了两个例子,一个post的,一个get的。

向豆瓣传数据,post:(我把说明都写到了注释中)

// "POST" 实例,以发一条状态为例
private void button1_Click(object sender, RoutedEventArgs e)
{
    //首先都要先实例化一个OAuthHeader,传入的参数为url和网络请求的方法(post or get or delete or put or something else)
    OAuthHeader header = new OAuthHeader("http://api.douban.com/miniblog/saying", "POST");

//对于post,要传给服务器一些数据,豆瓣api用xml来传数据,就需要先build一个xml的string
    StringBuilder requestBody = new StringBuilder("<?xml version='1.0' encoding='UTF-8'?>");
    requestBody.Append("<entry xmlns:ns0=\"http://www.w3.org/2005/Atom\" xmlns:db=\"http://www.douban.com/xmlns/\">");
    requestBody.Append("<content>hello world</content>");
    requestBody.Append("</entry>");

//下面两行是每一个网络请求都需要的,即与api.douban.com建立一个连接
    var client = new RestClient();
    client.BaseUrl = "http://api.douban.com";

//下面这行的意思是产生一个请求,第一个参数是路径名(不是完整的url),后面是Method.POST 或 Method.GET 或Method.PUT 或 Method.DELETE
    var request = new RestRequest("/miniblog/saying", Method.POST);

//下面进行一些http头的设置

//先设置request的format为xml
    request.RequestFormat = DataFormat.Xml;
    request.AddHeader("Content-Type", "application/atom+xml");

//然后是把生成的authorization写入http的header
    request.AddHeader("Authorization", header.getHeader());

//最终把要上传的数据写入http请求中,注意要加上ParameterType.RequestBody
    request.AddParameter("application/atom+xml", requestBody.ToString(), ParameterType.RequestBody);

//最后就是进行异步网络请求了,并且将传回的response的信息解析出来,呈现在页面上
    client.ExecuteAsync(request, (response) =>
    {
        var resource = response.Content;
        Debug.WriteLine(resource);
    });
}

//GET实例,以获取好友列表为例,get比较简单,不需要传入数据
private void button3_Click(object sender, RoutedEventArgs e)
{
    //同上
    OAuthHeader header = new OAuthHeader("http://api.douban.com/people/34788764/contacts?start-index=1&max-results=50", "GET");

var client = new RestClient();
    client.BaseUrl = "http://api.douban.com";

//注意,这里生成request的时候,不要把?后面的parameter加上,parameter要在后面的request.AddParameter处实现
    var request = new RestRequest("/people/34788764/contacts", Method.GET);

//加上认证头
    request.AddHeader("Authorization", header.getHeader());

//加上参数
    request.AddParameter("start-index", "1");
    request.AddParameter("max-results", "50");

client.ExecuteAsync(request, (response) =>
    {
        var resource = response.Content;
        Debug.WriteLine(resource);
        textBlock1.Text = resource;
    });
}

这样就可以大大简化网络请求,真正做到了don’t repeat yourself

豆瓣api之OAuth认证的更多相关文章

  1. 服务端API的OAuth认证实现

    http://stackoverflow.com/questions/12499602/body-joints-angle-using-kinect?rq=1 新浪微博跟update相关的api已经挂 ...

  2. 公网API安全--OAuth认证

    之前写过一个基于签名的公网API访问安全控制,另一种方式是基于OAuth认证协议做安全控制. 说明 用户访问A客户端,使用B的服务及资源.B只有征得用户的授权,才允许A客户端使用B上用户的资源和服务. ...

  3. 拿nodejs快速搭建简单Oauth认证和restful API server攻略

    拿nodejs快速搭建简单Oauth认证和restful API server攻略:http://blog.csdn.net/zhaoweitco/article/details/21708955 最 ...

  4. Android OAuth认证

    OAuth认证 为了安全地访问在线服务,用户需要在服务上进行身份验证,即要提供他们的身份的证明.对于一个要访问第三方服务的程序来说,安全问题甚至更复杂.不仅仅是用户需要在访问服务前要进行身份验证,而且 ...

  5. OAuth认证协议原理分析及同步消息到Twitter和Facebook使用方法

    OAuth有什么用?为什么要使用OAuth? twitter或豆瓣用户一定会发现,有时候,在别的网站,点登录后转到 twitter登录,之后转回原网站,你会发现你已经登录此网站了,这种网站就是这个效果 ...

  6. 新浪微博API Oauth2.0 认证

    原文链接: http://rsj217.diandian.com/post/2013-04-17/40050093587 本意是在注销账号前保留之前的一些数据.决定用python 爬取收藏.可是未登录 ...

  7. OAuth认证原理及HTTP下的密码安全传输

    很多人都会问这样一个问题,我们在登录的时候,密码会不会泄露?随便进一个网站,登录时抓包分析,可以看到自己的密码都是明文传输的,在如此复杂的web环境下,我们没有百分的把握保证信息在传输过程中不被截获, ...

  8. HTTP下密码的安全传输、OAuth认证

    在复杂的web环境下,我们没有百分的把握保证信息在传输的过程中不被接货,那不是用明文如何告诉服务器自己的身份呢? 在一些高度通信安全的网络中,数据传输会使用HTTPS作为传输协议,但是通常情况下我们没 ...

  9. 一步一步搭建 OAuth 认证服务器

    http://www.fising.cn/2011/03/%E4%B8%80%E6%AD%A5%E4%B8%80%E6%AD%A5%E6%90%AD%E5%BB%BA-oauth-%E8%AE%A4% ...

随机推荐

  1. 【课程分享】基于plusgantt的项目管理系统实战开发(Spring3+JDBC+RMI的架构、自己定义工作流)

    基于plusgantt的项目管理系统实战开发(Spring3+JDBC+RMI的架构.自己定义工作流) 课程讲师:张弘 课程分类:Java 适合人群:中级 课时数量:37课时 用到技术:Spring  ...

  2. 低压电力采集平台DW710C与PC沟通

    集电极485接口RS-485与RS-232转换模块485端相连.RS-485与RS-232转换模块232通过串行电缆末端PC的232串口.我们通过书面沟通PC通信软件来实现双方并执行收购方案. 1)上 ...

  3. PowerDesigner 为sql生成凝视

    在使用pd时发现生成的语句中没有行凝视,这样就得手动来加这些凝视,后来在网上找了一些方法.确实得到了解决,分享一下. 在Database-->edit Current DBMS... 设置dbm ...

  4. 【007】【JVM——内存分配和恢复策略】

     内存分配与收回策略 JVM的自己主动内存管理要自己主动化地解决两个问题:对象分配内存以及回收分配给对象的内存.回收内存前几篇已经讲了.如今说内存分配.对象的内存分配一般分配在堆内存中,也可能经过 ...

  5. 玩转Web之Jsp(一)-----jsp中的静态包含(<%@include file="url"%>)与动态包含(<jsp:include>)

    在jsp中include有两种形式,其中<%@include file="url"%>是指令元素,<jsp:include page="" f ...

  6. 使用autoconf和automake生成Makefile文件(转)

    Makefile好难写 曾经也总结了一篇关于Makefile的文章<make和makefile的简单学习>.但是,总结完以后,发现写Makefile真的是一件非常痛苦的事情,的确非常痛苦. ...

  7. MyEclipse—怎样在MyEclipse中创建servlet3.0

    servlet3.0随着Java EE6规范一起公布,那么怎样在MyEclipse中创建3.0版的servlet呢? 1.启动MyEclipse.获得下图: 2.点击上图"File" ...

  8. JAVA设计模式--辛格尔顿

    Singleton模式可以作为一种编程技术,让我们先从理论上说代码 单例模式三个关键点: 1).某个类仅仅能有一个实例 2).该类必须自行创建这个实例 3).该类必须自行向整个系统提供这个实例 应用场 ...

  9. 设备MyEclipse6.5的maven

    设备MyEclipse6.5的maven A.首先删除MyEclipse6.5自带的maven 删除步骤: 1.关闭MyEclipse,进入MyEclipse6.5安装目录,搜索maven,将搜索结果 ...

  10. ubuntu-14.04 系统安装mysql-5.6.21

    1.安装mysql前准备工作  (1).从官网下载mysql-5.6.21.tar.gz  (2).tar -zxvf mysql-5.6.21-tar.gz  会生成mysql-5.6.21的目录 ...