iOS开发项目篇—19获取授权过的访问标记
一、简单说明
1.获取授权
2.简单说明
说明:
(1)只能使用post请求
(2)post请求的参数有5个,且五个参数都是必须的。
(3)新浪会返回一个JSON,转成OC对象为字典,可以通过Key取出ACCESS_TOKEN。
二、实现
1.导入第三方框架
2.使用字典封装请求参数,五个参数都是必须的,就算少一个都是非法请求。
封装代码
1 //2.封装请求参数 2 /* 3 url:https://api.weibo.com/oauth2/access_token 4 必选 类型及范围 说明 5 client_id true string 申请应用时分配的AppKey。 6 client_secret true string 申请应用时分配的AppSecret。 7 grant_type true string 请求的类型,填写authorization_code 8 9 grant_type为authorization_code时 10 必选 类型及范围 说明 11 code true string 调用authorize获得的code值。 12 redirect_uri true string 回调地址,需需与注册应用里的回调地址一致。 13 */ 14 NSMutableDictionary *params=[NSMutableDictionary dictionary]; 15 params[@"client_id"] =@"1972915028"; 16 params[@"client_secret"] =@"b255603c4dfd82b4785bf9a808ce2662"; 17 params[@"grant_type"] =@"authorization_code"; 18 params[@"code"] =code; 19 params[@"redirect_uri"] =@"http://www.cnblogs.com/wendingding/";
关于请求失败的说明:
1 /** 2 * 根据code获得一个accessToken(发送一个Post请求) 3 * @param code 授权成功后的请求标记 4 */ 5 -(void)accessTokenWithCode:(NSString *)code 6 { 7 //处理操作.... 8 //1.获得请求管理者 9 AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager]; 10 11 //2.封装请求参数 12 NSMutableDictionary *params=[NSMutableDictionary dictionary]; 13 params[@"client_id"] =@"1972915028"; 14 params[@"client_secret"] =@"b255603c4dfd82b4785bf9a808ce2662"; 15 params[@"grant_type"] =@"authorization_code"; 16 params[@"code"] =code; 17 params[@"redirect_uri"] =@"http://www.cnblogs.com/wendingding/"; 18 19 //3.发送Post请求 20 [mgr POST:@"https://api.weibo.com/oauth2/access_token" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { 21 YYLog(@"请求成功--%@",[responseObject class]); 22 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 23 YYLog(@"请求失败--%@",error); 24 }]; 25 } 26 @end
查看结果:
错误说明:Request failed: unacceptable content-type: text/plain
服务器告诉客户端,返回的是 text/plain类型的数据,但是AFN默认只支持JSON和xml,并不支持这种普通的文本格式。
解决办法:
mgr.responseSerializer为设置服务器返回的类型。默认情况下为:mgr.responseSerializer=[AFJSONRequestSerializer serializer];
1 //1.获得请求管理者 2 AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager]; 3 4 // mgr.responseSerializer=[AFJSONRequestSerializer serializer]; 5 mgr.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"text/plain", nil];
这种方法会直接覆盖AFN原有的接收类型JSON,所以建议在AFN内部添加接收类型。
调整和的代码:
1 // 2 // YYOAuthViewController.m 3 // 08-微博弹出菜单 4 // 5 6 #import "YYOAuthViewController.h" 7 #import "MBProgressHUD+MJ.h" 8 #import "AFNetworking.h" 9 10 @interface YYOAuthViewController ()<UIWebViewDelegate> 11 12 @end 13 14 @implementation YYOAuthViewController 15 16 - (void)viewDidLoad 17 { 18 [super viewDidLoad]; 19 20 //1.创建UIWebView 21 UIWebView *webView=[[UIWebView alloc]init]; 22 webView.frame=self.view.bounds; 23 [self.view addSubview:webView]; 24 25 26 //2.加载登陆界面 27 NSURL *url=[NSURL URLWithString:@"https://api.weibo.com/oauth2/authorize?client_id=1972915028&redirect_uri=http://www.cnblogs.com/wendingding/"]; 28 NSURLRequest *request=[[NSURLRequest alloc]initWithURL:url]; 29 [webView loadRequest:request]; 30 31 //3.设置代理 32 webView.delegate=self; 33 } 34 35 #pragma mark-UIWebViewDelegate 36 /** 37 * UIWebView开始加载资源的时候调用(开始发送请求) 38 */ 39 -(void)webViewDidStartLoad:(UIWebView *)webView 40 { 41 [MBProgressHUD showMessage:@"正在努力加载中···"]; 42 } 43 44 /** 45 * UIWebView加载完毕的时候调用(请求结束) 46 */ 47 -(void)webViewDidFinishLoad:(UIWebView *)webView 48 { 49 [MBProgressHUD hideHUD]; 50 } 51 52 /** 53 * UIWebView加载失败的时候调用(请求失败) 54 */ 55 -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error 56 { 57 [MBProgressHUD hideHUD]; 58 } 59 60 /** 61 * UIWebView每当发送一个请求之前,都会先调用这个代理方法(询问代理允不允许加载这个请求) 62 * @param request 即将发送的请求 63 * @return YES允许加载,NO不允许加载 64 */ 65 -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 66 { 67 //1.获得请求地址 68 NSString *urlStr=request.URL.absoluteString; 69 70 //2.判断url是否为回调地址 71 /* 72 https://api.weibo.com/oauth2/authorize?client_id=1972915028&redirect_uri=http://www.cnblogs.com/wendingding/ 73 https://api.weibo.com/oauth2/authorize 74 https://api.weibo.com/oauth2/authorize# 75 76 https://api.weibo.com/oauth2/authorize 77 range.location==(-1)NSNoFound 78 range.length==0 79 http://www.cnblogs.com/wendingding/?code=c3dca3b51ab954bac42ebdb253661e4d 80 range.location==0 81 range.length>0 82 */ 83 //urlStr在字符串中的范围 84 //设置从等号位置开始,不用再额外的找位置 85 NSRange range=[urlStr rangeOfString:@"http://www.cnblogs.com/wendingding/?code="]; 86 //判断是否为回调地址 87 if (range.location!=NSNotFound) {//是回调地址 88 //截取授权成功后的请求标记 89 int from=range.location+range.length; 90 NSString *code=[urlStr substringFromIndex:from]; 91 92 //根据code获得一个accessToken 93 [self accessTokenWithCode:code]; 94 95 //禁止加载回调页面,拿到想要的东西就好了。 96 return NO; 97 } 98 return YES; 99 } 100 /** 101 * 根据code获得一个accessToken(发送一个Post请求) 102 * @param code 授权成功后的请求标记 103 */ 104 -(void)accessTokenWithCode:(NSString *)code 105 { 106 //处理操作.... 107 //1.获得请求管理者 108 AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager]; 109 // mgr.responseSerializer.acceptableContentTypes=[NSSet setWithObjects:@"text/plain", nil]; 110 111 //2.封装请求参数 112 /* 113 url:https://api.weibo.com/oauth2/access_token 114 必选 类型及范围 说明 115 client_id true string 申请应用时分配的AppKey。 116 client_secret true string 申请应用时分配的AppSecret。 117 grant_type true string 请求的类型,填写authorization_code 118 119 grant_type为authorization_code时 120 必选 类型及范围 说明 121 code true string 调用authorize获得的code值。 122 redirect_uri true string 回调地址,需需与注册应用里的回调地址一致。 123 */ 124 125 NSMutableDictionary *params=[NSMutableDictionary dictionary]; 126 params[@"client_id"] =@"1972915028"; 127 params[@"client_secret"] =@"b255603c4dfd82b4785bf9a808ce2662"; 128 params[@"grant_type"] =@"authorization_code"; 129 params[@"code"] =code; 130 params[@"redirect_uri"] =@"http://www.cnblogs.com/wendingding/"; 131 //3.发送Post请求 132 [mgr POST:@"https://api.weibo.com/oauth2/access_token" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*responseObject) { 133 YYLog(@"请求成功--%@",responseObject); 134 } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 135 YYLog(@"请求失败--%@",error); 136 }]; 137 138 // Request failed: unacceptable content-type: text/plain 139 } 140 @end
获取授权过的访问标记
说明:
(1)不会再次跳转到授权页面(之前已经拿到了授权标记),多次登录,新浪服务器返回的数据是一样的。
(2)uid==user_id==当前用户的ID,是用户的唯一标识,将来你需要获取当前用户的个人信息,那么就需要把uid传递给新浪的服务器,uid是当前用户在新浪数据库的主键。
(3)access_token:保证某一个应用能够访问某一个用户的数据,只要应用和用户是固定的,那么access_token就是固定的。
(4)两者的区别:
access_token:一个用户给一个应用授权成功后,就获得一个对应的acess_token。作用:允许一个应用访问一个用户的数据。
uid:一个用户对应一个uid,每个用户都有自己唯一的uid。
举例:有A和B两个用户,a,b两个应用,A用户给a,b两个应用授权成功了,B用户给b应用授权成功了。则产生了两个uid,3个access_token。
iOS开发项目篇—19获取授权过的访问标记