本文对iOS第三方登录流程进行整理总结,以微信为例,附第三方登录认证原理
首先要到微信开放平台注册登录账号,并创建移动应用程序。创建完成后会对应该程序生成一个 appid 和 appSecret 。然后申请该程序的微信登录功能。
1. 下载微信sdk
2. 将sdk引入工程
3. 添加URL scheme
4. 向微信终端程序注册第三方应用,并在第三方应用实现从微信返回
注册appid
5. 请求CODE
在要微信授权登录的controller中引入"WXApi.h"头文件,编写请求code的代码
#pragma mark 处理微信第三方登录
-(void)sendAuthRequestViewController:(UIViewController*)viewController
{
//构造SendAuthReq结构体
SendAuthReq* req =[[SendAuthReq alloc ] init ];
req.scope = @"snsapi_userinfo,snsapi_base";
req.state = @"123d324d444";
//第三方向微信终端发送一个SendAuthReq消息结构
//兼容未安装微信APP的请求
__weak typeof(self) weakSelf = self;
[WXApi sendAuthReq:req viewController:viewController delegate:weakSelf];
}
6通过 code 获取到accessToken以及openid
-(void)getWXAccessTokenWith:(SendAuthResp*)resp
{
NSString *url =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",WeiXinAppID,WeiXinAppSecret,resp.code];
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];
NSString *access_token = [dic objectForKey:@"access_token"];
NSString *refrshToken = [dic objectForKey:@"refresh_token"];
NSString *openid = [dic objectForKey:@"openid"];
[self getWXUserInfoWithOpenID:openid accessToken:access_token refreshToken:refrshToken];
}
});
});
}
7. 通过accessToken及openid调用API,获取用户信息
请求 @"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",accessToken,openID
获取openID,unionID等
-(void)getWXUserInfoWithOpenID:(NSString*)openID accessToken:(NSString*) accessToken refreshToken:(NSString*)refreshToken
{
NSString *url =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",accessToken,openID];
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];
SL_Log(@"userinfo :%@",dic);
if (!dic) { return ; }
SouFunThirdLoginModel *model = [[SouFunThirdLoginModel alloc] init];
model.openID = [NSString stringWithFormat:@"%@",[dic objectForKey:@"openid"]];
model.headImageURL = [dic objectForKey:@"headimgurl"];
model.userName = [dic objectForKey:@"nickname"];
model.nickName = [dic objectForKey:@"nickname"];
NSString *strSex = [NSString stringWithFormat:@"%@",[dic objectForKey:@"sex"]];
model.sex = [strSex isEqualToString:@"1"] ? @"男" : @"女";
model.accessToken = accessToken;
model.refreshToken = refreshToken;
model.unionID = [NSString stringWithFormat:@"%@",[dic objectForKey:@"unionid"]];
model.language = [dic objectForKey:@"language"];
model.province = [dic objectForKey:@"province"];
model.city = [dic objectForKey:@"city"];
model.thirdType = @"weixin";
if ([model.openID isEqualToString:@"(null)"] || [model.openID isEqualToString:@"null"] || model.openID.length<=1) {
return;
}else{
if (self.thirdBlock) {
self.thirdBlock(model);
}
}
}
});
});
}
8. auth 2.0认证
OAuth
允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。
OAuth 2.0是OAuth的下一个版本,但是不兼容1.0
认证授权过程
在认证和授权的过程中涉及的三方包括:
- 服务提供方,用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。
- 用户,存放在服务提供方的受保护的资源的拥有者。
- 客户端,要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站。在认证过程之前,客户端要向服务提供者申请客户端标识。
使用OAuth进行认证和授权的过程如下所示:
- 用户想操作存放在服务提供方的资源。
- 用户登录客户端向服务提供方请求一个临时令牌。
- 服务提供方验证客户端的身份后,授予一个临时令牌。
- 客户端获得临时令牌后,将用户引导至服务提供方的授权页面请求用户授权。在这个过程中将临时令牌和客户端的回调连接发送给服务提供方。
- 用户在服务提供方的网页上输入用户名和密码,然后授权该客户端访问所请求的资源。
- 授权成功后,服务提供方引导用户返回客户端的网页。
- 客户端根据临时令牌从服务提供方那里获取访问令牌。
- 服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌。
- 客户端使用获取的访问令牌访问存放在服务提供方上的受保护的资源。