iOS -第三方登录(SSO授权)原生接入(微博,QQ,微信)

原文网址:http://www.jianshu.com/p/7e3c5fc31708

0.demo说明
别的先不说demo地址如下
1.demo下载下来以后,请在WTThirdPartyLoginManager里面将自己的个平台的app key写上去.
2.URL Schemes 也请各位自己配置好
demo地址
材料准备
首先我们需要调料有 (点击链接下载~)
新浪微博sdk
腾讯sdk
微信sdk

微信登录官方文档

微博获取用户信息接口连接1
微博获取用户信息接口连接2

1.首先什么是第三登录?
答: 第三方登录就去微博,微信,QQ这些app上,拿用户的信息. 拿到了然后发到自己公司的服务器完成注册. 其实就是去第三方应用上拿用户的信息.
微信简单流程: 1.拿code--->2.用code换access_token--->3.用access_token换用户相关信息--->4.登录成功
微博: 跳转到微博客户端---->2.拿到accessToken,和userID---->3.拿用户信息
QQ: 跳转到QQ----->2.回来调用代理方法getUserInfo, ---->3.再调用代理方法返回用户信息

看着上面的流程是不是优点蒙?, 先别管,先记住,如果是微信的话,你要做两次网络请求让后最终拿到用户信息, 微博的话你只需做一次网络请求就ok, QQ的话你就直接调方法就行了网络请求什么的不用你烦.
2.需要哪些配置?
详细配置可以参考我的---iOS-新浪微博,QQ,微信分享原生接入记录,登录和分享的这些配置都是一样的, 也可以参考demo,直接!
①.首先添加这三个应用的sdk
②.添加白名单
③.添加 -ObjC,编译选项
④.添加 URL Tyes
⑤. 为了适配iOS9以上,你需要在info.plist里面再配置允许http访问
⑥.添加依赖库
允许http

// 主要还微博那家伙,虽然他是https的,证书当然也没问题,不过他的TLS版本太低了,所以拿微博信息的时候,如果不配置,iOS9以上的手机就拿不到信息.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

Snip20160704_1.png
有关HTTPS的相关,证书什么的资料,参考这个

注意点 新浪微博你可能会遇到如下
1.redirect_uri_mismatch
你的回调地址错误,
解决办法:去新浪开放平台修改回调地址;
2.sso package or sign error
这个是你app 的Bundle identifier 和新浪开放平台上的Bundle ID不一致. 去开放平台上修改一下就好.
如图注意要一一对齐

Bundle identifier 对应

Snip20160704_4.png
回调页对应

Snip20160704_8.png
app key 对应

Snip20160704_5.png
代码简介
和分享一样我提供了一个WTThirdPartyLoginManager管理各个平台的
登录,提供了如下的一个类方法

  • (void)getUserInfoWithWTLoginType:(WTLoginType)type result:(WTThirdPartyLoginResultBlock)result;
    1.首先你得在WTThirdPartyLoginManager.m配置好了各平台的信息
    2.确保你的URL Schemes 也配置好
    传入不同的WTLoginType跳转到不同的客户端!
    下面是WTThirdPartyLoginManager的具体代码
    WTThirdPartyLoginManager.h
    //
    // WTThirdPartyLoginManager.h
    // WTThird_Party_Login
    //
    // Created by Mac on 16/7/2.
    // Copyright © 2016年 wutong. All rights reserved.
    //

import <Foundation/Foundation.h>

import "WeiboSDK.h"

import "WXApi.h"

import <TencentOpenAPI/TencentOAuth.h>

import <TencentOpenAPI/QQApiInterfaceObject.h>

import <TencentOpenAPI/QQApiInterface.h>

typedef NS_ENUM(NSInteger, WTLoginType) {
WTLoginTypeWeiBo = 0, // 新浪微博
WTLoginTypeTencent, // QQ
WTLoginTypeWeiXin // 微信
};

typedef NS_ENUM(NSInteger, WTLoginWeiXinErrCode) {
WTLoginWeiXinErrCodeSuccess = 0,
WTLoginWeiXinErrCodeCancel = -2,

};

typedef void(^WTThirdPartyLoginResultBlock)(NSDictionary * LoginResult, NSString * error);

@interface WTThirdPartyLoginManager : NSObject<TencentSessionDelegate, TencentLoginDelegate,WBHttpRequestDelegate,WeiboSDKDelegate,WXApiDelegate>

  • (instancetype)shareWTThirdPartyLoginManager;

  • (void)getUserInfoWithWTLoginType:(WTLoginType)type result:(WTThirdPartyLoginResultBlock)result;

@end
WTThirdPartyLoginManager.m
//
// WTThirdPartyLoginManager.m
// WTThird_Party_Login
//
// Created by Mac on 16/7/2.
// Copyright © 2016年 wutong. All rights reserved.
//

import "WTThirdPartyLoginManager.h"

define kSinaAppKey @"你自己微博的Appkey"//

define kSinaRedirectURI @"你设置的微博回调页"

define kTencentAppId @"你的腾讯开放平台的appId"

define kWeixinAppId @"微信id"

define kWeixinAppSecret @"AppSecret"

@interface WTThirdPartyLoginManager () <NSCopying,NSURLSessionTaskDelegate>
{

}
@property (nonatomic, copy)WTThirdPartyLoginResultBlock resultBlock;
@property (nonatomic, assign)WTLoginType wtLoginType;
@property (nonatomic, strong)NSString * access_token;

@property (nonatomic, strong)TencentOAuth * tencentOAuth;
@property (nonatomic, strong)NSMutableArray * tencentPermissions;

@end

@implementation WTThirdPartyLoginManager

static WTThirdPartyLoginManager * _instance;

  • (void)initialize
    {
    [WTThirdPartyLoginManager shareWTThirdPartyLoginManager];
    }

  • (instancetype)allocWithZone:(struct _NSZone *)zone
    {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    _instance = [super allocWithZone:zone];
    [_instance setRegisterApps];
    });
    return _instance;
    }

  • (instancetype)shareWTThirdPartyLoginManager
    {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    _instance = [[self alloc]init];
    [_instance setRegisterApps];
    });
    return _instance;
    }

  • (id)copyWithZone:(nullable NSZone *)zone
    {
    return _instance;
    }

// 注册app
// 注册appid

  • (void)setRegisterApps
    {
    // 注册Sina微博
    [WeiboSDK registerApp:kSinaAppKey];
    // 微信注册
    [WXApi registerApp:kWeixinAppId];

    // 注册QQ
    _tencentOAuth = [[TencentOAuth alloc]initWithAppId:kTencentAppId andDelegate:self];
    // 这个是说到时候你去qq那拿什么信息
    _tencentPermissions = [NSMutableArray arrayWithArray:@[/** 获取用户信息 /
    kOPEN_PERMISSION_GET_USER_INFO,
    /
    * 移动端获取用户信息 /
    kOPEN_PERMISSION_GET_SIMPLE_USER_INFO,
    /
    * 获取登录用户自己的详细信息 */
    kOPEN_PERMISSION_GET_INFO]];
    }

  • (void)getUserInfoWithWTLoginType:(WTLoginType)type result:(WTThirdPartyLoginResultBlock)result
    {
    _instance.resultBlock = result;
    _instance.wtLoginType = type;
    if (type == WTLoginTypeWeiBo) {
    WBAuthorizeRequest *request = [WBAuthorizeRequest request];
    request.redirectURI = kSinaRedirectURI;
    // request.scope = @"follow_app_official_microblog";

      [WeiboSDK sendRequest:request];
    

    }else if (type == WTLoginTypeTencent){

      [_instance.tencentOAuth authorize:_instance.tencentPermissions];
    

    }else if (type == WTLoginTypeWeiXin){
    //构造SendAuthReq结构体
    SendAuthReq* req =[[SendAuthReq alloc ] init ];
    req.scope = @"snsapi_userinfo" ;
    //第三方向微信终端发送一个SendAuthReq消息结构
    [WXApi sendReq:req];
    }
    }

pragma mark - WXApiDelegate

-(void) onResp:(BaseResp*)resp
{
SendAuthResp *aresp = (SendAuthResp *)resp;

if (resp.errCode == WTLoginWeiXinErrCodeSuccess) {
    NSString *code = aresp.code;
    [[WTThirdPartyLoginManager shareWTThirdPartyLoginManager] getWeiXinUserInfoWithCode:code];
}else{

    if (self.resultBlock)
    {
        self.resultBlock(nil, @"授权失败");
    }
}

}

  • (void)getWeiXinUserInfoWithCode:(NSString *)code
    {
    NSOperationQueue * queue = [[NSOperationQueue alloc]init];

    NSBlockOperation * getAccessTokenOperation = [NSBlockOperation blockOperationWithBlock:^{

      NSString * urlStr = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",kWeixinAppId,kWeixinAppSecret,code];
      NSURL * url = [NSURL URLWithString:urlStr];
      NSString *responseStr = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
      NSData *responseData = [responseStr dataUsingEncoding:NSUTF8StringEncoding];
      NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
      self.access_token = [dic objectForKey:@"access_token"];
    

    }];

    NSBlockOperation * getUserInfoOperation = [NSBlockOperation blockOperationWithBlock:^{
    NSString *urlStr =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",self.access_token,kWeixinAppId];
    NSURL * url = [NSURL URLWithString:urlStr];
    NSString *responseStr = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
    NSData *responseData = [responseStr dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
    NSDictionary *paramter = @{@"third_id" : dic[@"openid"],
    @"third_name" : dic[@"nickname"],
    @"third_image":dic[@"headimgurl"],
    @"access_token":self.access_token};

      [[NSOperationQueue mainQueue] addOperationWithBlock:^{
    
          //                _resultBlock;
          self.resultBlock(paramter, nil);
      }];
    

    }];

    [getUserInfoOperation addDependency:getAccessTokenOperation];

    [queue addOperation:getAccessTokenOperation];
    [queue addOperation:getUserInfoOperation];
    }

pragma mark - TencentLoginDelegate

//委托

  • (void)tencentDidLogin
    {
    [_tencentOAuth getUserInfo];
    }

  • (void)getUserInfoResponse:(APIResponse *)response
    {
    if (response.retCode == URLREQUEST_SUCCEED)
    {
    NSLog(@"%@", response.jsonResponse);
    NSLog(@"openID %@", [_tencentOAuth openId]);
    NSDictionary *paramter = @{@"third_id" : [_tencentOAuth openId],
    @"third_name" : [response.jsonResponse valueForKeyPath:@"nickname"],
    @"third_image":[response.jsonResponse valueForKeyPath:@"figureurl_qq_2"],
    @"access_token":[_tencentOAuth accessToken]};

      if (self.resultBlock)
      {
          self.resultBlock(paramter, nil);
      }
    

    }
    else
    {
    NSLog(@"登录失败!");
    }
    }

  • (void)tencentDidLogout
    {

}

  • (void)tencentDidNotLogin:(BOOL)cancelled
    {

}

  • (void)tencentDidNotNetWork
    {

}

pragma mark - WeiboSDKDelegate

  • (void)didReceiveWeiboRequest:(WBBaseRequest *)request
    {

}

  • (void)didReceiveWeiboResponse:(WBBaseResponse *)response
    {
    NSLog(@"token %@", [(WBAuthorizeResponse *) response accessToken]);
    NSLog(@"uid %@", [(WBAuthorizeResponse *) response userID]);

    [self getWeiBoUserInfo:[(WBAuthorizeResponse *) response userID] token:[(WBAuthorizeResponse *) response accessToken]];
    }

  • (void)getWeiBoUserInfo:(NSString *)uid token:(NSString *)token
    {
    NSString *url =[NSString stringWithFormat:@"https://api.weibo.com/2/users/show.json?uid=%@&access_token=%@&source=%@",uid,token,kSinaAppKey];
    NSURL *zoneUrl = [NSURL URLWithString:url];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    // 创建任务
    NSURLSessionDataTask * task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:zoneUrl] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

      NSLog(@"%@", [NSThread currentThread]);
    
      NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
      NSLog(@"%@",dic);
    
      NSDictionary *paramter = @{@"third_id" : [dic valueForKeyPath:@"idstr"],
                                 @"third_name" : [dic valueForKeyPath:@"screen_name"],
                                 @"third_image":[dic valueForKeyPath:@"avatar_hd"],
                                 @"access_token":token};
    
      [[NSOperationQueue mainQueue] addOperationWithBlock:^{
          if (self.resultBlock)
          {
              _resultBlock(paramter, nil);
          }
      }];
    

    }];

    // 启动任务
    [task resume];
    }

@end
demo下载
1.demo下载下来以后,请在WTThirdPartyLoginManager里面将自己的个平台的app key写上去.
2.URL Schemes 也请各位自己配置好
demo地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容