现在的位置: 首页 > 综合 > 正文

第三方授权

2014年08月27日 ⁄ 综合 ⁄ 共 5600字 ⁄ 字号 评论关闭

一直对使用开放平台的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。

  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.       
  5.     //在视图中添加WebView组件:web  
  6.     web = [[UIWebView alloc] initWithFrame:self.view.frame];  
  7.     [self.view addSubview:web];  
  8.     web.delegate = self;//设定web的委托为自己  
  9.       
  10.     //在视图中添加一个活动指示器:acti_view  
  11.     acti_view = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0.0, 0.0, 32.0, 32.0)];  
  12.     acti_view.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;  
  13.     acti_view.center = self.view.center;  
  14.     [self.view addSubview:acti_view];  
  15.       
  16.     //在web视图中向服务器发送请求,默认方式是HTTP GET  
  17.     //GET_AUTHORIZATION_CODE是获取用户授权页面的完整API地址  
  18.     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:GET_AUTHORIZATION_CODE]];  
  19.     [self.web loadRequest:request];  
  20. }  

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

  1. @interface ViewController : UIViewController <UIWebViewDelegate>  

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

  1. //是否在网页视图中加载重定向后的页面  
  2. -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType  
  3. {  
  4.     NSString *redirect = [[request URL] absoluteString];//获得回调网址  
  5.     //NSLog(@"bool method %@", [request URL].absoluteString);  
  6.     if ([redirect hasPrefix:[NSString stringWithFormat:@"%@?code=", CALLBACK_URL]])//判断回调网址的前缀,看返回结果是否authorization_code  
  7.     {  
  8.         NSRange codeRange = [redirect rangeOfString:@"code="];//获取code=的范围  
  9.         NSUInteger fromIndex = codeRange.location + codeRange.length;//获取authorization_code字符串的起始位置  
  10.         NSString *auth_code = [redirect substringFromIndex:fromIndex];//获取用户授权的authorization_code  
  11.         NSLog(@"auth code = %@", auth_code);  
  12.           
  13.         //建立获取令牌的完整api网址  
  14.         NSString *urlStr = [NSString stringWithFormat:@"%@%@", GET_ACCESS_TOKEN, auth_code];  
  15.         NSURL *token_url = [NSURL URLWithString:urlStr];  
  16.           
  17.         //建立url请求  
  18.         NSMutableURLRequest *token_request = [[NSMutableURLRequest alloc] initWithURL:token_url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];  
  19.         [token_request setHTTPMethod:@"POST"];//设置请求方式为POST,默认为GET  
  20.         NSString *str = @"type=focus-c";//设置参数  
  21.         NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];  
  22.         [token_request setHTTPBody:data];  
  23.           
  24.         //向服务器发送HTTP POST请求  
  25.         NSData *received = [NSURLConnection sendSynchronousRequest:token_request returningResponse:nil error:nil];  
  26.         NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:received options:kNilOptions error:nil];//将NSData数据转换成NSDictionary  
  27.         NSString *access_token = [dic objectForKey:@"access_token"];//获取access_token  
  28.         NSString *expires_in = [dic objectForKey:@"expires_in"];  
  29.         NSString *refresh_token = [dic objectForKey:@"refresh_token"];  
  30.         NSString *douban_user_id = [dic objectForKey:@"douban_user_id"];  
  31.         NSLog(@"access_token = %@", access_token);  
  32.         NSLog(@"expires_in = %@", expires_in);  
  33.         NSLog(@"refresh_token = %@", refresh_token);  
  34.         NSLog(@"douban_user_id = %@", douban_user_id);  
  35.     }  
  36.       
  37.     return YES;  
  38. }  
  39.   
  40. //网页视图开始加载数据  
  41. -(void)webViewDidStartLoad:(UIWebView *)webView  
  42. {  
  43.     NSLog(@"Start");  
  44.     [acti_view startAnimating];//活动指示器开始活动,表示正在加载数据  
  45. }  
  46.   
  47. //网页视图完成加载数据  
  48. -(void)webViewDidFinishLoad:(UIWebView *)webView  
  49. {  
  50.     NSLog(@"Finsih");  
  51.     [acti_view stopAnimating];//活动指示器停止,表示加载数据完成  
  52. }  
  53.   
  54. //加载数据出错处理  
  55. -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error  
  56. {  
  57.     NSLog(@"Error");  
  58. }  

运行结果:

模拟器输出:

控制台输出:

  1. 2013-07-27 14:56:41.281 WebViewDelegate_Demo[8357:11303] Start  
  2. 2013-07-27 14:56:41.858 WebViewDelegate_Demo[8357:11303] Finsih  
  3. 2013-07-27 14:56:54.115 WebViewDelegate_Demo[8357:11303] Start  
  4. 2013-07-27 14:56:54.355 WebViewDelegate_Demo[8357:11303] auth code = fb69cb9b6e9c3f9b  
  5. 2013-07-27 14:56:55.077 WebViewDelegate_Demo[8357:11303] access_token = 57588db612baa0db0609a922382fe291  
  6. 2013-07-27 14:56:55.077 WebViewDelegate_Demo[8357:11303] expires_in = 604800  
  7. 2013-07-27 14:56:55.077 WebViewDelegate_Demo[8357:11303] refresh_token = 9a1d42a3fc0b2b03ce57c7ebf4218109  
  8. 2013-07-27 14:56:55.077 WebViewDelegate_Demo[8357:11303] douban_user_id = 75816695  
  9. 2013-07-27 14:57:08.092 WebViewDelegate_Demo[8357:11303] Finsih  

最后小结一下:

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

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

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

更多0

抱歉!评论已关闭.