豆瓣客户端(一)获取用户授权的access_token

一直对使用开放平台的API写应用的方法非常感兴趣,直到昨天才真正开始接触这方面的内容。

国内的开发平台很多,我的几位团友都是做新浪微博开始的,所以我不打算跟他们做出一个模子的东西,淘宝的开发者认证有点麻烦,百度和腾讯不喜欢,最后我选择了自己较为感兴趣的豆瓣。下面讲讲我学习的整个过程:

调用开放平台的API做应用都是从看该平台提供的开发文档开始的,豆瓣的开发文档链接为:http://developers.douban.com/wiki/?title=guide

要访问豆瓣的API必须使用OAuth2.0,使用流程为:

1.应用向豆瓣申请授权(新建应用时完成)

2.豆瓣的应用调用api向用户展示一个授权页面,用户在该页面上确认是否同意授权给应用

3.如果用户同意授权,应用将获得一个authorization_code

4.程序通过参数authorization_code向服务器发送请求,随后获取一个访问令牌(access_token),通过该令牌,应用可以访问授权用户的数据

因此,要访问用户的数据,首先就要拿到用户授权的访问令牌access_token。刚开始学习这方面的内容,遇上了不少的问题,让我一直卡了好久。

我创建的应用是移动客户端应用:native-application flow,授权流程和flow相同,必须通过两步来获取access_token。

第一步,获取authorization_code。也就是调用一个豆瓣的API向用户显示一个授权页面,若用户同意授权应用将获得对应的authorization_code。这个非常简单,首先在应用的测试用户选项中手动添加测试用户的uid,相信下面的文档会有代码方法实现。然后在浏览器地址栏中输入完整的api地址获得,也可以在代码中实现。其中api完整地址的填写方法在文档中已有详细说明。在用户同意授权后将转到回调页面,从该回调网址中可以获得authorization_code。

- (void)viewDidLoad
{
    [super viewDidLoad];

    //在视图中添加WebView组件:web
    web = [[UIWebView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:web];
    web.delegate = self;//设定web的委托为自己

    //在视图中添加一个活动指示器:acti_view
    acti_view = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 32.0, 32.0)];
    acti_view.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
    acti_view.center = self.view.center;
    [self.view addSubview:acti_view];

    //在web视图中向服务器发送请求,默认方式是HTTP GET
    //GET_AUTHORIZATION_CODE是获取用户授权页面的完整API地址
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:GET_AUTHORIZATION_CODE]];
    [self.web loadRequest:request];
}

第二步,获取access_token。在这里我就完全卡住了,我以为同样地是在地址栏中输入完整的api地址就可以在回调页面中获取令牌字符串,但是回调页面中显示错误,原因是该请求是HTTP GET方式,而文档中注明该请求必须是HTTP POST方式,后来看了团友Crayon_Dys的博客才知道必须用代码方法指定参数向服务器发送请求。首先要声明该类实现UIWebViewDelegate:

@interface ViewController : UIViewController <UIWebViewDelegate>

然后在协议方法中具体实现:

//是否在网页视图中加载重定向后的页面
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *redirect = [[request URL] absoluteString];//获得回调网址
    //NSLog(@"bool method %@", [request URL].absoluteString);
    if ([redirect hasPrefix:[NSString stringWithFormat:@"%@?code=", CALLBACK_URL]])//判断回调网址的前缀,看返回结果是否authorization_code
    {
        NSRange codeRange = [redirect rangeOfString:@"code="];//获取code=的范围
        NSUInteger fromIndex = codeRange.location + codeRange.length;//获取authorization_code字符串的起始位置
        NSString *auth_code = [redirect substringFromIndex:fromIndex];//获取用户授权的authorization_code
        NSLog(@"auth code = %@", auth_code);

        //建立获取令牌的完整api网址
        NSString *urlStr = [NSString stringWithFormat:@"%@%@", GET_ACCESS_TOKEN, auth_code];
        NSURL *token_url = [NSURL URLWithString:urlStr];

        //建立url请求
        NSMutableURLRequest *token_request = [[NSMutableURLRequest alloc] initWithURL:token_url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
        [token_request setHTTPMethod:@"POST"];//设置请求方式为POST,默认为GET
        NSString *str = @"type=focus-c";//设置参数
        NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
        [token_request setHTTPBody:data];

        //向服务器发送HTTP POST请求
        NSData *received = [NSURLConnection sendSynchronousRequest:token_request returningResponse:nil error:nil];
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:received options:kNilOptions error:nil];//将NSData数据转换成NSDictionary
        NSString *access_token = [dic objectForKey:@"access_token"];//获取access_token
        NSString *expires_in = [dic objectForKey:@"expires_in"];
        NSString *refresh_token = [dic objectForKey:@"refresh_token"];
        NSString *douban_user_id = [dic objectForKey:@"douban_user_id"];
        NSLog(@"access_token = %@", access_token);
        NSLog(@"expires_in = %@", expires_in);
        NSLog(@"refresh_token = %@", refresh_token);
        NSLog(@"douban_user_id = %@", douban_user_id);
    }

    return YES;
}

//网页视图开始加载数据
-(void)webViewDidStartLoad:(UIWebView *)webView
{
    NSLog(@"Start");
    [acti_view startAnimating];//活动指示器开始活动,表示正在加载数据
}

//网页视图完成加载数据
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSLog(@"Finsih");
    [acti_view stopAnimating];//活动指示器停止,表示加载数据完成
}

//加载数据出错处理
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    NSLog(@"Error");
}

最后小结一下:

1.开放平台提供的api是一个网址,在建立带参数的完整网址并发送http请求后,服务器将返回一个应用接口给调用程序。例如输入上面获取authorization_code的api地址发送http请求后将在应用界面显示一个用户授权页面。网址相当于一个方法,调用该方法后将获得开放接口返回的功能界面或开发者想要获取的数据。

2.http的post方式必须通过代码方法实现,可以在发送请求时通过参数 HTTPMethod 指定。

3.获取用户个人信息的基本步骤:调用接口建立一个用户授权页面——用户同意授权——在回调网址中获得authorization_code——填写参数authorization_code的内容并调用接口获取json数据——在json数据中获取access_token——通过令牌获得用户信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信中控服务器(一个获取微信 access_token 和 ticket 的服务).zip wechat-token-proxy 是一个获取微信 access_token 和 ticket 的服务。它能使调用微信公众号各接口的各个业务逻辑点共享 access_token 和 ticket ,避免产生冲突。 说到这个冲突,就得先了解微信的 access_token 。引用微信官方的描述: access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取access_token失效。 如果第三方不使用中控服务器,而是选择各个业务逻辑点各自去刷新access_token,那么就可能会产生冲突,导致服务不稳定。 详见微信官网 微信限定每天只能调用2000次刷新access_token的接口。换言之,每次调用公众号接口时都刷新access_token的话,很有可能超出2000次/日的限制。 开发 wechat-token-proxy 的目的,是为了让众多的业务逻辑点能和谐调用微信公众号的接口,共享access_token,减少一个令业务服务不稳定的因素。 项目文件说明 |文件名|功能简介| |:--------:|------| |conf/wx_config.json|设置微信 app_id 和 app_secret| |destinations/wx_flush_access_token.js|获取access_token| |shipper.js|将access_token写到文件, 或读取access_token| |refresher/wx_access_token.json|此文件保存access_token的值| |schedule.js|定时执行wx_flush_access_token.js| |app.js|通过http方式输出json格式的access_token| |conf/access.json|设置允许访问此服务的 IP 或 域名| 如何使用 由于使用了 express 框架,启动 wechat-token-proxy 只需要执行 app.js 文件。具体步骤如下: clone 项目 git clone .git 进入 wechat-token-proxy 文件夹,并安装依赖模块 cd wechat-token-proxy npm install 设置 conf/wx_config.json 和 conf/access.json 两个文件。 wx_config.json 内容如下: { "app_id": "微信公众号的AppID", "app_secret": "微信公众号的AppSecret" } access.json 内容如下: { "ip": ["127.0.0.1"], "hostname": ["localhost"] } 启动项目 node app.js 打开浏览器 访问 http://localhost:3000 获取 access_token; 访问 http://localhost:3000/ticket 获取 ticket。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值