由于公司项目需要,从微信登录和支付功能刚开始内测的时候,就开始研究微信登陆,不过当时可怜的微信的sdk,demo里面的sdk不是最新的,压根没找到发送登录的SendAuthReq这个类,耽误了一两天,真坑爹,最后把所有的资源下载下来,都看看才搞定,如果有需要的,给我留言就OK!
下面开始说下微信接入的步骤:主要也是按照微信的开发平台:https://open.weixin.qq.com/cgi-bin/frame?t=resource/res_main_tmpl&verify=1&lang=zh_CN
1.向微信注册你的应用程序id
首先你需要像微信商务注册你的应用程序的id,这个功能是要收费的,貌似一点五六百块钱的吧。
2.下载微信终端SDK文件sdk文件
3.搭建开发环境
1、把上述三个文件导入工程
4、在你需要使 用微信终端API的文件中import WXApi.h 头文件,并增加 WXApiDelegate 协议。
5、在代码中使用开发工具包
1)、要使你的程序启动后微信终端能响应你的程序,必须在代码中向微信终端注册你的id。(如下图所示,在 AppDelegate 的 didFinishLaunchingWithOptions 函数中向微信注册id)。
2)、重写AppDelegate的handleOpenURL和openURL方法:
3)、现在,你的程序要实现和微信终端交互的具体请求与回应,因此需要实现WXApiDelegate协议的两个方法:
上面微信的接入已经完成,下面就是用户授权操作:
授权流程说明
微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。
微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:
- 1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
- 2.通过code参数加上AppID和AppSecret等,通过API换取access_token;
- 3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
第一步:请求CODE
移动应用微信授权登录
开发者需要配合使用微信开放平台提供的SDK进行授权登录请求接入。正确接入SDK后并拥有相关授权域(scope,什么是授权域?)权限后,开发者移动应用会在终端本地拉起微信应用进行授权登录,微信用户确认后微信将拉起开发者移动应用,并带上授权临时票据(code)。
IOS平台应用授权登录接入代码示例(请参考IOS接入指南):
-(void)sendAuthRequest
{
//构造SendAuthReq结构体
SendAuthReq* req =[[[SendAuthReq alloc ] init ] autorelease ];
req.scope = @"snsapi_userinfo" ;
req.state = @"123" ;
//第三方向微信终端发送一个SendAuthReq消息结构
[WXApi sendReq:req]; }
//点你点击允许授权登录按钮,允许用户授权的时候,即可回调此方法
-(void) onResp:(BaseResp*)resp
{
SendAuthResp * resp1 = (SendAuthResp *)resp;
}
第二步:通过code获取access_token
获取第一步的code后,请求以下链接获取access_token:
返回说明
正确的返回:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
第三步:通过access_token调用接口,获取用户个人信息(UnionID机制)
获取access_token后,进行接口调用,有以下前提:
- 1. access_token有效且未超时;
- 2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。
接口说明
此接口用于获取用户个人信息。开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。
请求说明
http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
返回说明
正确的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"
}
- (void)viewDidLoad
{
[superviewDidLoad];
UIButton * loginWeiXin = [UIButtonbuttonWithType:UIButtonTypeCustom];
[loginWeiXinsetFrame:CGRectMake(100,100, 100, 100)];
loginWeiXin.backgroundColor = [UIColorredColor];
[loginWeiXin addTarget:selfaction:@selector(loginWeiXinWithBtn:)forControlEvents:UIControlEventTouchUpInside];
[self.viewaddSubview:loginWeiXin];
}
#pragma mark - 按钮响应的方法
-(void)loginWeiXinWithBtn:(UIButton *)sender
{
if ([WXApiisWXAppInstalled]) {
//构造SendAuthReq结构体
SendAuthReq* req =[[SendAuthReqalloc ] init ] ;
req.scope =@"snsapi_userinfo," ;
req.state =@"123123" ;
//第三方向微信终端发送一个SendAuthReq消息结构
[WXApisendReq:req];
}else{
UIAlertView *alertView = [[UIAlertViewalloc] initWithTitle:@"温馨提示" message:@"您没有安装微信,是否去下载" delegate:self cancelButtonTitle:@"取消"otherButtonTitles:@"确定",nil];
[alertViewshow];
}
}
AppDelegate.m实现方法是:
//点你点击确认登录按钮,允许用户授权的时候,即可回调此方法
-(void) onResp:(BaseResp*)resp
{
SendAuthResp * resp1 = (SendAuthResp *)resp
NSLog(@"%@",resp1.code);
NSLog(@"%@",resp1.errStr);
NSLog(@"%d",resp1.type);
if (resp1.errCode ==WXSuccess) {
//用户允许授权登录
//第二步通过code获取access_token
NSString * codeStr = resp1.code;
NSString * grantStr =@"grant_type=authorization_code";
//通过code获取access_token https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
NSString * tokenUrl =@"https://api.weixin.qq.com/sns/oauth2/access_token?";
NSString * tokenUrl1 = [tokenUrl stringByAppendingString:[NSString stringWithFormat:@"appid=%@&",weixinLoginAppId]];
NSString * tokenUrl2 = [tokenUrl1 stringByAppendingString:[NSString stringWithFormat:@"secret=%@&",weixinLoginAppSecret]];
NSString * tokenUrl3 = [tokenUrl2 stringByAppendingString:[NSString stringWithFormat:@"code=%@&",codeStr]];
NSString * tokenUrlend = [tokenUrl3 stringByAppendingString:grantStr];
NSLog(@"%@",tokenUrlend);
NSURL *url = [NSURLURLWithString:tokenUrlend];
ASIHTTPRequest * request = [[ASIHTTPRequestalloc]initWithURL:url];
[request setDefaultResponseEncoding:NSUTF8StringEncoding];
[requestsetRequestMethod:@"GET"];
[requeststartSynchronous];
NSString * str =request.responseString;
NSDictionary * dic = [str objectFromJSONString];//把此句转化为傻逼
NSLog(@"%@",[dicobjectForKey:@"access_token"]);
NSString * access_token = [dic objectForKey:@"access_token"];
//NSString * expires_in = [dic objectForKey:@"expires_in"];
//NSString * refresh_token = [dic objectForKey:@"refresh_token"];
NSString * openid = [dic objectForKey:@"openid"];
//第三步:通过access_token得到昵称、unionid等信息
NSString * userfulStr = [NSStringstringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",access_token,openid];
NSURL * userfulUrl = [NSURLURLWithString:userfulStr];
ASIHTTPRequest * userfulRequest = [[ASIHTTPRequestalloc]initWithURL:userfulUrl];
[userfulRequestsetRequestMethod:@"GET"];
[userfulRequestsetDefaultResponseEncoding:NSUTF8StringEncoding];
[userfulRequeststartSynchronous];
NSString * userfulResultStr =userfulRequest.responseString;
NSDictionary * userfulResultDic =[userfulResultStrobjectFromJSONString];
NSLog(@"%@",userfulResultDic);
//NSString * unionidStr = [userfulResultDic objectForKey:@"unionid"];//每个用户所对应的每个开放平台下的每个应用是同一个唯一标识
NSString * nickStr = [userfulResultDic objectForKey:@"nickname"];
}else {
//登录失败
}
}
这就是微信登录的具体过程了,由于时间问题,使用了同步请求,这样是不怎么合理的,有时间再改。