前言
前段时间公司的 APP 加了一些新需求,其中我负责的钱包模块多增加了支付宝绑定和支付宝支付的功能。所以研究了一番,在此做个记录,如果有说的不对的地方,欢迎大佬指出并纠正。
支付宝授权
支付宝授权其实就是使用支付宝第三方登录,需要用户同意授权,使用支付宝登录你的 APP,这样你的 APP 就可以通过支付宝 SDK 提供的接口去获取对应的支付宝信息。例如:你的支付宝账户的唯一标示等。
-
支付宝授权流程图
支付宝授权流程
- APP 向自己后台发起授权请求,后台给 APP 返回授权码,其实就是一个带着私钥的字符串。
- APP 拿着后台返回的授权码去向支付宝发起授权请求。
- 支付宝返回给 APP 当次授权的授权码
app_auth_code
和开发者的app_id
。 - 拿到支付宝返回的当前授权的授权码
app_auth_code
发送给自己的后台去换取app_auth_token
。 - 用换取的
app_auth_token
去调用支付宝提供的alipay.open.auth.token.app
接口去获取授权用户的userId
。
- 支付宝授权代码示例
首先你需要去下载支付宝提供的官方 Demo,然后把官方 Demo 里的APAuthInfo
拷贝到你的项目里。
#import <Foundation/Foundation.h>
@interface APAuthInfo : NSObject
/*********************************授权必传参数*********************************/
//服务接口名称,常量com.alipay.account.auth。
@property (nonatomic, copy) NSString *apiname;
//调用方app标识 ,mc代表外部商户。
@property (nonatomic, copy) NSString *appName;
//调用业务类型,openservice代表开放基础服务
@property (nonatomic, copy) NSString *bizType;
//产品码,目前只有WAP_FAST_LOGIN
@property (nonatomic, copy) NSString *productID;
//签约平台内的appid
@property (nonatomic, copy) NSString *appID;
//商户签约id
@property (nonatomic, copy) NSString *pid;
//授权类型,AUTHACCOUNT:授权;LOGIN:登录
@property (nonatomic, copy) NSString *authType;
//商户请求id需要为unique,回调使用
@property (nonatomic, copy) NSString *targetID;
/*********************************授权可选参数*********************************/
//oauth里的授权范围,PD配置,默认为kuaijie
@property (nonatomic, copy) NSString *scope;
//固定值,alipay.open.auth.sdk.code.get
@property (nonatomic, copy) NSString *method;
@end
其中APAuthInfo
中的appID
、pid
、targetID
这三个参数是需要我们自己去赋值的。appID
就是你申请的 APP 在支付宝平台的唯一标识,pid
是你申请的 APP 在支付宝平台对应的商户号,targetID
是保证每次请求的时候它的值是唯一的,所以一般赋值为当前时间的时间戳。
APAuthInfo *authInfo = [APAuthInfo new];
authInfo.pid = AliPayPid;
authInfo.appID = AliPayID;
authInfo.targetID = [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]];
// 将授权信息拼接成字符串
NSString *authInfoStr = [authInfo description];
NSLog(@"authInfoStr = %@",authInfoStr);
然后向自己后台去请求获取私钥和私钥加密方式,拿到私钥以及私钥加密方式只后拼接成指定格式的字符串,拿这个字符串去发起支付宝授权。
authInfoStr = [NSString stringWithFormat:@"%@&sign=%@&sign_type=%@", authInfoStr, sign, @"RSA2"];
[[AlipaySDK defaultService] auth_V2WithInfo:authInfoStr fromScheme:appScheme callback:^(NSDictionary *resultDic) {
NSLog(@"resultDic = %@", resultDic);
// 解析 auth code
NSString *result = resultDic[@"result"];
[self handlderAliPayAuthInfo:result];
}];
最后,拿到支付宝授权接口的返回值,取result
字段所对应的字符串,然后截取出我们需要的auth_code
和alipay_open_id
。然后再把这两个值传给后端,由后端去调取支付宝接口去获取用户信息。
- (void)handlderAliPayAuthInfo:(NSString *)result {
NSString *authCode = nil;
NSString *openId = nil;
if (result.length > 0) {
NSArray *resultArr = [result componentsSeparatedByString:@"&"];
for (NSString *subResult in resultArr) {
if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
authCode = [subResult substringFromIndex:10];
}
if (subResult.length > 32 && [subResult hasPrefix:@"alipay_open_id="]) {
openId = [subResult substringFromIndex:15];
}
if (openId.length != 0 && authCode.length != 0) {
break;
}
}
}
NSLog(@"授权结果 authCode = %@, openId = %@", authCode?:@"", openId?:@"");
}
注意
- 应用授权的
app_auth_code
是唯一的;app_auth_code
使用一次后就会失效,一天(从生成app_auth_code
开始的24小时)未被使用就会自动过期;app_auth_token
有效期为365天,刷新后重新计时。 - 支付宝的私钥必须存放在后端,不能存放在前段。因为在支付宝平台申请 APP 的时候就会生产一对私钥和公钥,只有当你穿的私钥和支付宝平台存放的公钥相配对成功之后,授权请求才会成功。所以,如果把私钥存放在前段会存在很大的危险漏洞,因此只能把私钥存放在后端。