一、接入微信第三方登录准备工作。
移动应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。
在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。(注意)
1、下载iOS微信SDK。
下载地址

ziyuan.png

2、将SDK放到工程目录中。

wechat.png

3、补充导入一些依赖框架。

kuangjia.png

4、添加URL Types

info.png

5、添加iOS9 URL Schemes.

Schemes.png

注意:如果没有做这步的话会出现以下错误.

-canOpenURL: failed for URL: "weixin://app/wx9**********dfd30/" - error: "This app is not allowed to query for scheme weixin"

6、iOS9中新增App Transport Security(简称ATS)特性, 主要使到原来请求的时候用到的HTTP,都转向TLS1.2协议进行传输。这也意味着所有的HTTP协议都强制使用了HTTPS协议进行传输。需要在Info.plist新增一段用于控制ATS的配置:

<key>NSAppTransportSecurity</key>
<dict><key>NSAllowsArbitraryLoads</key><true/>
</dict>

security.png

如果我们在iOS9下直接进行HTTP请求是会收到如下错误提示:

**App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.**

7、向微信终端程序注册第三方应用,并在第三方应用实现从微信返回
在AppDelegate.m中引入"WXApi.h"头文件,然后写入如下:

#import "AppDelegate.h"
#import "LoginViewController.h"
#import "WXApi.h"#pragma mark - application delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {[WXApi registerApp:@"wxd1931d4a0e46****" withDescription:@"Wechat"];
return YES;
}
// 这个方法是用于从微信返回第三方App
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {[WXApi handleOpenURL:url delegate:self];
return YES;
}

8、请求CODE
开发者需要配合使用微信开放平台提供的SDK进行授权登录请求接入。正确接入SDK后并拥有相关授权域(scope,什么是授权域?)权限后,开发者移动应用会在终端本地拉起微信应用进行授权登录,微信用户确认后微信将拉起开发者移动应用,并带上授权临时票据(code)。

#import "LoginViewController.h"
#import "RegisterViewController.h"
#import "MBProgressHUD.h"
#import "AFNetworking.h"
#import "WXApi.h"#pragma mark - 微信登录
/*目前移动应用上德微信登录只提供原生的登录方式,需要用户安装微信客户端才能配合使用。对于iOS应用,考虑到iOS应用商店审核指南中的相关规定,建议开发者接入微信登录时,先检测用户手机是否已经安装微信客户端(使用sdk中的isWXAppInstall函数),对于未安装的用户隐藏微信 登录按钮,只提供其他登录方式。*/
- (IBAction)wechatLoginClick:(id)sender {if ([WXApi isWXAppInstalled]) {SendAuthReq *req = [[SendAuthReq alloc] init];req.scope = @"snsapi_userinfo";req.state = @"App";[WXApi sendReq:req];}else {[self setupAlertController];}
}#pragma mark - 设置弹出提示语
- (void)setupAlertController {UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"请先安装微信客户端" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction *actionConfirm = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];[alert addAction:actionConfirm];[self presentViewController:alert animated:YES completion:nil];
}

执行完上面那一步后,如果客户端安装了微信,那么就会向微信请求相应的授权,图如下:

微信授权.png

还有在实际的使用中我们还要结合需求做一些改变。因为微信授权后access_token(2小时)之类的字段都是有效期的在有效期范围内,我们是没必要让用户再次授权的,很可能你的实现,会如我下面所写的(LoginViewController)

// LoginViewController.h
#import <UIKit/UIKit.h>
@interface LoginViewController : BaseViewController
/** 通过block去执行AppDelegate中的wechatLoginByRequestForUserInfo方法 */
@property (copy, nonatomic) void (^requestForUserInfoBlock)();
@end// LoginViewController.m
#pragma mark - 微信登录
/*目前移动应用上德微信登录只提供原生的登录方式,需要用户安装微信客户端才能配合使用。对于iOS应用,考虑到iOS应用商店审核指南中的相关规定,建议开发者接入微信登录时,先检测用户手机是否已经安装微信客户端(使用sdk中的isWXAppInstall函数),对于未安装的用户隐藏微信 登录按钮,只提供其他登录方式。*/
- (IBAction)wechatLoginClick:(id)sender {NSString *accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:WX_ACCESS_TOKEN];NSString *openID = [[NSUserDefaults standardUserDefaults] objectForKey:WX_OPEN_ID];// 如果已经请求过微信授权登录,那么考虑用已经得到的access_tokenif (accessToken && openID) {AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];NSString *refreshToken = [[NSUserDefaults standardUserDefaults] objectForKey:WX_REFRESH_TOKEN];NSString *refreshUrlStr = [NSString stringWithFormat:@"%@/oauth2/refresh_token?appid=%@&grant_type=refresh_token&refresh_token=%@", WX_BASE_URL, WXPatient_App_ID, refreshToken];[manager GET:refreshUrlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {NSLog(@"请求reAccess的response = %@", responseObject);NSDictionary *refreshDict = [NSDictionary dictionaryWithDictionary:responseObject];NSString *reAccessToken = [refreshDict objectForKey:WX_ACCESS_TOKEN];// 如果reAccessToken为空,说明reAccessToken也过期了,反之则没有过期if (reAccessToken) {// 更新access_token、refresh_token、open_id[[NSUserDefaults standardUserDefaults] setObject:reAccessToken forKey:WX_ACCESS_TOKEN];[[NSUserDefaults standardUserDefaults] setObject:[refreshDict objectForKey:WX_OPEN_ID] forKey:WX_OPEN_ID];[[NSUserDefaults standardUserDefaults] setObject:[refreshDict objectForKey:WX_REFRESH_TOKEN] forKey:WX_REFRESH_TOKEN];[[NSUserDefaults standardUserDefaults] synchronize];// 当存在reAccessToken不为空时直接执行AppDelegate中的wechatLoginByRequestForUserInfo方法!self.requestForUserInfoBlock ? : self.requestForUserInfoBlock();}else {[self wechatLogin];}} failure:^(AFHTTPRequestOperation *operation, NSError *error) {NSLog(@"用refresh_token来更新accessToken时出错 = %@", error);}];}else {[self wechatLogin];}
}
- (void)wechatLogin {if ([WXApi isWXAppInstalled]) {SendAuthReq *req = [[SendAuthReq alloc] init];req.scope = @"snsapi_userinfo";req.state = @"GSTDoctorApp";[WXApi sendReq:req];}else {[self setupAlertController];}
}
#pragma mark - 设置弹出提示语
- (void)setupAlertController {UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"请先安装微信客户端" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction *actionConfirm = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];[alert addAction:actionConfirm];[self presentViewController:alert animated:YES completion:nil];
}
当有access_token和openID时输出:
**请求****reAccess****的****response = {**
**    "access_token" = "OezXcEiiBSKSxW0eoylIeK3BOTSVaRovFSXb5oysH6dewFfLsQRgU3fphSLkKkhOokra9H-JMZuB5nPoM-Iy5YbFeA1nKMRYCbL0fj_s46oFKOluGoRUY8jyTdrdDiiFdgS2fxgo5odEtpnpFk3EXA";**
**    "expires_in" = 7200;**
**    openid = oXskgs62CJGFhFX05dSjy9Sjw2KA;**
**    "refresh_token" = "OezXcEiiBSKSxW0eoylIeK3BOTSVaRovFSXb5oysH6dewFfLsQRgU3fphSLkKkhOOWPTKGEjUtuiueutxRjKOlHGZ9b9ogc3KMbibu4eKc4yTMGzSZayjYPmwQ-c4RJE1RzMLrqvjUWgB5roFnjykw";**
**    scope = "snsapi_base,snsapi_userinfo,";**
**}**

刷新access_token有效期:
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:

1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。

refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。
让AppDelegate遵守<WXApiDelegate>协议,并实现协议方法onResp:
,我们在该方法中接收请求回来的数据,如下:

//授权后回调
/*http请求方式:GET// 根据响应结果中的code获取access_token(要用到申请时得到的AppID和AppSecret)https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code正确返回{"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE","unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"}错误返回样例{"errcode":40029,"errmsg":"invalid code"}ErrCode ERR_OK = 0(用户同意)ERR_AUTH_DENIED = -4(用户拒绝授权)ERR_USER_CANCEL = -2(用户取消)code    用户换取access_token的code,仅在ErrCode为0时有效state   第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1Klang    微信客户端当前语言country 微信用户当前国家信息*/
-(void)showLoginController:(BOOL)shouldAnimation
{LoginViewController *loginController=[[LoginViewController alloc]initWithNibName:@"LoginViewController" bundle:nil];loginController.requestForUserInfoBlock = ^() {[[AppDelegate sharedInstance] wechatLoginByRequestForUserInfo];};BaseNavigationController *baseNavController=[[BaseNavigationController alloc]initWithRootViewController:loginController];[kAppDelegate.window.rootViewController presentViewController:baseNavController animated:shouldAnimation completion:NULL];
}
// 授权后回调
// AppDelegate.m
- (void)onResp:(BaseResp *)resp {// 向微信请求授权后,得到响应结果if ([resp isKindOfClass:[SendAuthResp class]]) {        SendAuthResp *temp = (SendAuthResp *)resp;AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];NSString *accessUrlStr = [NSString stringWithFormat:@"%@/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code", WX_BASE_URL, WXPatient_App_ID, WXPatient_App_Secret, temp.code];[manager GET:accessUrlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {NSLog(@"请求access的response = %@", responseObject);NSDictionary *accessDict = [NSDictionary dictionaryWithDictionary:responseObject];NSString *accessToken = [accessDict objectForKey:WX_ACCESS_TOKEN]; NSString *openID = [accessDict objectForKey:WX_OPEN_ID];NSString *refreshToken = [accessDict objectForKey:WX_REFRESH_TOKEN];// 本地持久化,以便access_token的使用、刷新或者持续if (accessToken && ![accessToken isEqualToString:@""] && openID && ![openID isEqualToString:@""]) {[[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:WX_ACCESS_TOKEN];[[NSUserDefaults standardUserDefaults] setObject:openID forKey:WX_OPEN_ID];[[NSUserDefaults standardUserDefaults] setObject:refreshToken forKey:WX_REFRESH_TOKEN];[[NSUserDefaults standardUserDefaults] synchronize]; // 命令直接同步到文件里,来避免数据的丢失}[self wechatLoginByRequestForUserInfo];} failure:^(AFHTTPRequestOperation *operation, NSError *error) {NSLog(@"获取access_token时出错 = %@", error);}];}
}

9、通过code获取access_token
通过上一步获取的code后,请求以下链接获取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

相关代码上面实现onResp:方法,接收返回的响应。
参数说明

参数           是否必须        说明
appid           是             应用唯一标识,在微信开放平台提交应用审核通过后获得
secret          是             应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code            是             填写第一步获取的code参数
grant_type      是             填authorization_code

返回说明

{
"access_token":"ACCESS_TOKEN", // 接口调用凭证"expires_in":7200, // access_token接口调用凭证超时时间,单位(秒)
"refresh_token":"REFRESH_TOKEN", // 用户刷新access_token
"openid":"OPENID",  // 授权用户唯一标识
"scope":"SCOPE", // 用户授权的作用域,使用逗号(,)分隔
"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL" // 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段
}

错误返回样例:

{"errcode":40029,"errmsg":"invalid code"}

10、获取用户个人信息(UnionID机制)

http请求方式:GEThttps://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
// AppDelegate.m
// 获取用户个人信息(UnionID机制)
- (void)wechatLoginByRequestForUserInfo {AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];NSString *accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:WX_ACCESS_TOKEN];NSString *openID = [[NSUserDefaults standardUserDefaults] objectForKey:WX_OPEN_ID];NSString *userUrlStr = [NSString stringWithFormat:@"%@/userinfo?access_token=%@&openid=%@", WX_BASE_URL, accessToken, openID];// 请求用户数据[manager GET:userUrlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {NSLog(@"请求用户信息的response = %@", responseObject);// NSMutableDictionary *userDict = [NSMutableDictionary dictionaryWithDictionary:responseObject];} failure:^(AFHTTPRequestOperation *operation, NSError *error) {NSLog(@"获取用户信息时出错 = %@", error);}];
}

返回的Json结果:

返回的Json结果{"openid":"OPENID","nickname":"NICKNAME","sex":1,"province":"PROVINCE","city":"CITY","country":"COUNTRY","headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0","privilege":["PRIVILEGE1","PRIVILEGE2"],"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"}返回错误的Json事例{"errcode":40003,"errmsg":"invalid openid"}

11、最后
做到上面一步就应该得到返回微信的基本信息,然后根据你公司后台的基本需求去实现授权后如何登录App.
资料:

// access_token openid refresh_token unionid
#define WXDoctor_App_ID @"wxd1931d4a0e462***"  // 注册微信时的AppID
#define WXDoctor_App_Secret @"d0dd6b58da42cbc4f4b715c70e65c***" // 注册时得到的AppSecret
#define WXPatient_App_ID @"wxbd02bfeea4292***"
#define WXPatient_App_Secret @"4a788217f363358276309ab655707***"
#define WX_ACCESS_TOKEN @"access_token"
#define WX_OPEN_ID @"openid"
#define WX_REFRESH_TOKEN @"refresh_token"
#define WX_UNION_ID @"unionid"
#define WX_BASE_URL @"https://api.weixin.qq.com/sns"
文/EvenCoder(简书作者)
原文链接:http://www.jianshu.com/p/0c3df308bcb3
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

IOS微信三方登陆(不错)相关推荐

  1. iOS 微信三方登陆

    第一种方法:直接集成微信SDK(不使用友盟) 一:官方文档说明 官方文档连接:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_li ...

  2. 微信php第三方登录接口,ThinkPHP实现微信三方登录

    小插曲就是app做微信三方登录是很久之前,后面又添加了PC的微信三方登陆,而文档上说unionid是同一个账号下不同应用统一的,但是app拿的是uid,导致pc拿的unionid始终对不上,导致浪费了 ...

  3. Android三方登陆之QQ,微信,微博登录及注意事项

    简介 在我们的应用中,一般都有三方登录这个功能,对于这个常用的功能,我们一般会有如下处理方式 导入三方sdk,按照文档开发 使用如ShareSDK类三方组件来实现 ShareSDK 官方Demo: T ...

  4. Java前后端分离第三方登录_网站前后端分离情况下如何实现QQ微信等第三方登陆-Fun言...

    前言 最近在弄第三方登录,实现起来很简单,就是调几个接口获取个人信息即可,详细了解:maven项目整合QQauth2.0第三方登录详细说明,然后因为本网站是前后端分离的,所以不能再回调接口那里直接跳转 ...

  5. 网站前后端分离情况下如何实现QQ微信等第三方登陆

    本文转自Fun言网:https://funyan.cn/p/1705.html 前言 最近在弄第三方登录,实现起来很简单,就是调几个接口获取个人信息即可,详细了解:maven项目整合QQauth2.0 ...

  6. 第三方登陆:微信官方登陆

    第三方登陆:微信官方登陆 一.首先进入微信授权登陆之前的一个验证,在微信开放平台注册开发者账号,并拥有一个已经审核通过的移动应用,获得相应的AppID和AppSecrect,申请微信通过审核后(如下如 ...

  7. Android淘宝三方登陆

    最近要做一个淘宝登陆,阿里的平台太杂乱了,走了一些弯路想记录一下 1. 阿里百川创建应用地址,这里应用名字必须是唯一性的,如果app的名字显示已注册过了,就没有办法用这个名字了,不过三方登陆的名字可以 ...

  8. iOS微信授权登录集成

    iOS微信授权登录集成 iOS微信授权登录集成,具体的过程参考官方的文档 微信集成官方Demo地址: iOS资源下载 不错的文章: iOS微信登录集成 iOS 微信第三方登录的简单实现 准备工作 1. ...

  9. iOS微信支付的步骤以及问题描述

    本博客转自:http://www.jianshu.com/p/22a1ceee4d36 一.微信支付的步骤: 1.在微信开放平台注册.微信开放平台 2.创建一个App应用.(需要填写App的资料,审核 ...

最新文章

  1. 【TarsosDSP】TarsosDSP 简介 ( TarsosDSP 功能 | 相关链接 | 源码和相关资源收集 | TarsosDSP 示例应用 | TarsosDSP 源码路径解析 )
  2. pythonos pathjson_Python Json数据文件操作原理解析
  3. 辽宁省2021年高考成绩位次查询,辽宁2021八省联考分数、位次表(非官方),附志愿填报样表...
  4. Winform中设置ZedGraph的曲线符号Symbol以及对应关系
  5. Visual Studio系统通用快捷键
  6. 【原创】网络报文抓取研究
  7. 关于《详解》第12.1节按键驱动的进一步阐述
  8. typecho和wordpress模板了解、开发流程介绍、前台后台前端后端区分
  9. 【转】linux内核态和用户态的区别
  10. linux运维常见英文报错中文翻译(菜鸟必知)
  11. zookeeper服务端
  12. office2007 ppt制作与应用母板
  13. Matlab实现 LU分解法解线性方程组(全选主元列选主元)
  14. windows和linux的icmp包,linux和windows下icmp的区别
  15. 哈!他们的“自我修养” 穆穆-movno1
  16. 高通平台开发系列讲解(系统篇)coredump
  17. 微信订阅号的订阅模式有哪些?
  18. 关于“灵魂”和“躯体”,上汽的回复其实是行业“标准答案”
  19. 包包各部位名称图解_包包各个部位的英文表达
  20. vscode通过插件一键运行 c++单元测试

热门文章

  1. 会玩Go!会玩Python!嘭!Go-Python!
  2. Cisco Umbrella
  3. MySQL最左匹配原则
  4. 人工智能 漆桂林_东南大学计算机科学与工程学院硕导介绍:漆桂林
  5. windows使用cmd连接ftp使用命令上传(put)和下载文件(mget)
  6. 网易开源游戏服务器框架-Pomelo实践(一)
  7. android maxlength 汉字,Android TextView maxWidth、maxLines、maxLength、maxEms
  8. 【疑难杂症】解决苹果MacOS升级提示“验证固件时发生错误”,无论如何都无法升级更新,主板Boot Rom、SMC版本号更新!
  9. Android studio:真机调试vivo X21手机安装失败
  10. 实现一下类似百度网盘的预览功能:支持Word、Excel、Ppt