您的位置:首页 > 移动开发 > IOS开发

基于OAuth2.0协议的QQ第三方授权登录iOS代码分析

2015-02-07 17:02 756 查看

简要说明:

授权登录已经成为注册方式里的主流,目前授权登录方式主要SSO跳转授权登录和OAuth2.0两种,前者好处无需用户再次输入密码就可以直接授权成功,但前提是必须用户手机端安装了该软件,比如QQ,后者的优势就是是否安装无关紧要,是一个HTML的页面呈现,麻烦就在于要输入用户名和密码,这就非常不爽了,但是有时候偏偏必须这么做,理由嘛,自行想想就好,接下来我们就看看如果利用OAuth2.0的方式来做QQ授权登录,如果想了解QQ的SSO授权登录,可以看我(博客主页)之前的博客:基于第三方QQ授权登录和新浪微博授权登录的iOS代码分析.

吐槽时间:

或许大家会说官方文档不是写的很清楚嘛,好吧,如果你这么相信,请关闭此博客,去看官方文档吧,理由无需多说,一句话:腾讯,你很任性。

学习须知:

1,QQ互联注册的APP_ID;
2,针对 iOS 或 Android开发者,原理一样;
3,了解OC/Java 与 JS 之间的交互方式;

核心代码:

1,采用UIWebView加载授权页面

qqWebView=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    qqWebView.backgroundColor = [UIColor whiteColor];
    qqWebView.delegate =self;  
    NSString *urlStr = [NSString stringWithFormat:@"https://graph.qq.com/oauth2.0/authorize?response_type=token&client_id=%@&display=mobile&redirect_uri=http://www.xxxxx.com",QQ_WEB_APP_ID];
    
    NSURLRequest *request=[[NSURLRequest alloc] initWithURL:[NSURL URLWithString:urlStr]];
    [qqWebView loadRequest:request];
    [qqWebView setUserInteractionEnabled:YES];
    
    [self.view addSubview:qqWebView];


以上代码就是打开授权页面,然后输入用户名和密码后点击登录,这一块资料可以查看官方文档:http://wiki.open.qq.com/wiki/website/OAuth2.0%E7%AE%80%E4%BB%8B

这里特别注意有个参数是response_type=token ,这个如果我们是移动端一定要传token,如果是PC端则传code,不然无法接着下面的步骤,切记。

2,利用UIWebView的代理方法截取返回的URL
原理就是我们利用这个代理方法不断的判断将要请求的是不是我们需要的URL,是JS和OC交互的方式,如果需要JS传值给OC,就是采用这种URL探测的方式,具体代码如下:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    NSString *requestString = [[[request URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
//    if ([requestString hasPrefix:@"QQLoginTest://"]) {
//        //如果是自己定义的协议, 再截取协议中的方法和参数, 判断无误后在这里手动调用oc方法

    return YES;
}
以上就是基本方式,下面看具体我们怎么获得我们需要的token和openid

3,获取需要的openid 和 token

if ([requestString hasPrefix:@"http://qzs.qq.com"]) {
        
        NSLog(@"requestString:%@",requestString);
        
        NSString *paramsStr = [[requestString componentsSeparatedByString:@"#&"] lastObject];
        NSArray *paramsArr = [paramsStr componentsSeparatedByString:@"&"];
        
        NSString *openid = [[paramsArr[0] componentsSeparatedByString:@"="] lastObject];
        NSString *token = [[paramsArr[2] componentsSeparatedByString:@"="] lastObject];
        
       
        [self getUserInfoWithToken:token openId:openid];
        
    }


4,获取我们需要的昵称和头像

- (void)getUserInfoWithToken:(NSString *)token openId:(NSString *)openid{
    
    // https://graph.qq.com/user/get_simple_userinfo?access_token=F6XXXXD005CCF705D&oauth_consumer_key=XXXX463&openid=40XXXBA5D8667C&format=json     
    NSString *url = [NSString stringWithFormat:@"https://graph.qq.com/user/get_simple_userinfo?access_token=%@&openid=%@&oauth_consumer_key=%@&format=json", token, openid,QQ_WEB_APP_ID];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
                   {
                       NSURL *zoneUrl = [NSURL URLWithString:url];
                       NSString *zoneStr = [NSString stringWithContentsOfURL:zoneUrl encoding:NSUTF8StringEncoding error:nil];
                       NSData *data = [zoneStr dataUsingEncoding:NSUTF8StringEncoding];
                       dispatch_async(dispatch_get_main_queue(), ^
                                      {
                                          if (data)
                                          {
                                              NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                                              //NSLog(@"DIC:%@",dic);
                                              // 登录成功 可以获取用户信息
                                              /*
                                               {
                                               "ret": 0,
                                               "msg": "",
                                               "is_lost": 0,
                                               "nickname": "ZZZZZZZ",
                                               "gender": "男",
                                               "province": "北京",
                                               "city": "海淀",
                                               "figureurl": "http://qzapp.qlogXXX32A09044BA5D8667C/30",
                                               "figureurl_1": "http://qzapp.qlogo.XXXXA09044BA5D8667C/50",
                                               "figureurl_2": "http://qzapp.qlogo.cnXXXX44BA5D8667C/100",
                                               "figureurl_qq_1": "http://q.qlogoXXXF89F646432A09044BA5D8667C/40",
                                               "figureurl_qq_2": "http://q.qlogo.XXXX46432A09044BA5D8667C/100",
                                               "is_yellow_vip": "0",
                                               "vip": "0",
                                               "yellow_vip_level": "0",
                                               "level": "0",
                                               "is_yellow_year_vip": "0"
                                               }
                                               */
                                            
                                              
                                              qqWebView.hidden = YES;
                                              self.head.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[dic objectForKey:@"figureurl_qq_2"]]]];
                                              self.nick.text = dic[@"nickname"];
                                              
                                          }
                                      });
                       
                   });
}
看到这里基本就完成了,具体逻辑就看产品本身的需要了,最后来看下各个阶段的效果图

效果图:





(完结,原创博客,转载请注明出处)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: