客户身份(CIAM)

微信登录

# 文档说明

本文为您介绍iOS客户端如何接入微信授权登录功能。微信登录使用场景下,用户手机上已安装了微信APP,用户点击客户端APP上微信登录按钮,IDaaS SDK调起微信APP里的授权页面,用户点击“授权登录”按钮,授权成功后,微信APP重定向回到客户端APP,此时IDaaS SDK自动接收到临时票据,带着票据到IDaaS 服务端请求认证。最终认证结果返回给客户端APP。

# 流程说明

# 登录流程

集成流程说明

  1. 用户点击APP客户端的微信登录按钮。

  2. APP客户端拉起IDaaS SDK的微信登录方法。

  3. IDaaS SDK发送登录授权请求到微信SDK。

  4. 微信SDK拉起手机上的微信APP,并显示授权登录页面。

  5. 用户点击授权登录按钮。

  6. 微信授权成功,拉起客户端APP,并且带上微信授权票据,此时,IDaaS SDK在调起中自动获取到微信授权票据。

  7. IDaaS用微信授权票据请求IDaaS服务端认证。

  8. IDaaS服务端查询是否绑定手机号,如果已经绑定手机号,IDaaS服务端认证成功,返回session_token和id_token给IDaaS SDK。

  9. IDaaS SDK将session_token和id_token返回给APP客户端。

  10. 如果IDaaS服务端查询到未绑定手机号,返回需要绑定或注册的标识。

  11. IDaaS服务端展示绑定或注册页面。

  12. 用户输入手机号,点击获取验证码,完成滑块验证。

  13. IDaaS SDK带着滑块验证码到IDaaS服务端请求滑块验证。

  14. IDaaS 服务端校验滑块成功,返回token给IDaaS SDK。

  15. IDaaS SDK用token和手机号到IDaaS 服务端请求发送短信验证码。

  16. 用户收到短信验证码,填入验证码输入框,并且点击绑定或注册按钮。

  17. IDaaS SDK提交绑定或登录数据到IDaaS 服务端。

  18. 绑定或注册成功,IDaaS服务端返回session_token和id_token给IDaaS SDK。

  19. IDaaS SDK返回session_token和id_token给客户端APP。

  20. 客户端可以使用id_token来校验登录有效期和获取用户基本信息。

  21. 客户端可以使用session_token来刷新id_token。

# 准备工作

# 微信开放平台创建应用

开发者登录微信开放平台 (opens new window),创建自己的开发账号,新建应用,审核通过。获取到应用的appID和app Secrete。

# 获取clientID

登录IDaaS企业中心平台,点击 “资源-->应用” 选择跟自己相关的应用点击即可查看到。

# 配置认证源

  1. 登录到IDaaS企业中心平台,点击“认证—>认证源管理—>微信”。

  2. 点击添加认证源,填入微信开发平台注册应用后得到的AppKey和AppSecrete。并且渠道选择框为‘移动应用’。显示名称填入名称。

  3. 点击确定,就会得到如下图的一条认证源。切换至“资源-->应用”,进入新建的应用,进入“登录配置—>移动应用—>配置”。

  4. 开启应用的微信认证源。

  5. 弹出如下图的窗口,选择刚才配置好的认证源保存即可。

# 引入依赖包

在进行微信 OAuth 授权登录接入之前,需在微信开放平台 (opens new window)注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的 AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。

libWeChatSDK.a //微信SDK包
WXApi.h
WXApiObject.h 
1
2
3

# 添加主库

AuthnCenter_common_2C.framework	  
AuthnCenter_Wechat_2C.framework  
AuthnCenter_Wechat_2C.bundle // 资源包
1
2
3

将IDaaSSDK拖入工程,并且引入方式如下:

并且引入Pod的依赖包。

pod 'JWT', '~> 3.0.0-beta.14'

# Targets设置

  • IDaaS短信登录SDK最低版本可兼容ios 12。

  • 在framework, library,and embedded content里引入以下包。

Security.framework, 
CoreGraphics.framework,
CoreMedia.framework,
UIKit.framework,
WebKit.framework,
libc++.tbd
1
2
3
4
5
6
  • 设置Other Linker Flags,在你的工程文件中选择 Build Setting,在"Other Linker Flags"中加入"-ObjC-all_load",在 Search Paths 中添加 libWeChatSDK.a ,WXApi.h,WXApiObject.h。

  • 设置url scheme,在 Xcode 中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”为你所注册的应用程序 id(如下图所示)。

  • 在Xcode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“LSApplicationQueriesSchemes“添加weixin和weixinULAPI(如下图所示)。

  • 设置bitcode为NO

# UniversalLink设置

  • 微信授权成功后需要拉起App客户端,需要配置universallink,请参照网上教程配置universallink。

首先确认微信的Universal Links正常。打开浏览器Safari输入https://help.wechat.com/app/。下拉查看是否有打开微信入口(如下图)。若无入口,可能是由于系统拉取微信Universal Links失败,请检查手机网络状态是否正常,或更新/重装微信。

  • Univerallink配置成功后需要在App客户端填入,按照下图步骤添加Associated Domains,并且按照下图格式填入universallink。

    Universal link的格式是:applinks:你的universallink

  • 设置Allow Non-modular Includes In Framework Modules 设置成Yes。

# 开发集成

# 内置UI页面的开发集成方式

本章节是APP客户端一次拉起微信登录。APP客户端只需要接入IDaaS SDK,初始化方法,微信注册方法,在需要拉起微信登录的地方调用IDaaS SDK微信登录方法,其余的认证、注册、绑定UI流程由IDaaS SDK完全提供。登录成功后由回调函数中返回sessionToken。

在本章节之前请完成上一章所有xcode配置和微信开放平台配置。

# SDK初始化

IDaaS SDK提供一个初始化方法,您可在初始化方法里填入租户,clientID和是否打开log日志打印。

初始化方法的示例:

在appdelegate中引用头文件如下
#import <AuthnCenter_common_2C/BCIDACommonManager.h>
#import <AuthnCenter_wechat_2C/BCWechatManager.h>

//在appdelegate 中的didFinishLaunchingWithOptions方法中
//1. 基本配置初始化
[[[[[BCIDACommonManager sharedInstance] initWithDomain:@"https://你的后台租户.com"] initWithClientID:@"后台租户clientID"] initWithSSLCerVerification:NO] setLogEnabled:YES] ;
//2.微信初始化
    [[BCWechatManager sharedInstance] registWechatAppid:@"微信开发平台APPID" andUniversalLink:@"配置好的universalLink"];
1
2
3
4
5
6
7
8
9

在appdelegate 中,下面几个方法接收来自微信的回调,这个回调会基于在微信平台配置好的universalLink,请先配置好universalLink。

-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    [[BCWechatManager sharedInstance] oauthHandleOpenURL:url];
     return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
    [[BCWechatManager sharedInstance] oauthHandleOpenURL:url];
  return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{

    [[BCWechatManager sharedInstance] oauthHandleOpenURL:url];
  
    return YES;
}
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{
   
    [[BCWechatManager sharedInstance] handleUniversalLink:userActivity];
    

    return YES;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

基本配置初始化主类BCIDACommonManager方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance ;

/**
  * 函数名:initWithDomain
   * @param domain,以https://开头,以.com结尾。
   * @return 实例类
 */
-(BCIDACommonManager)initWithDomain:(NSString)domain

/**
  * 函数名:initWithClientID
   * @param client id。
   * @return 实例类
 */
-(BCIDACommonManager)initWithClientID:(NSString)clientID;

/**
  * 函数名:setLogEnabled
   * @param 布尔值是否开启log。
   * @return 实例类
 */
-(void)setLogEnabled:(BOOL)enable;

/**
  * 函数名:initWithSSLCerVerification
   * @param 布尔值设置ssl证书是否开启检测。
   * @return 实例类
 */
-(BCIDACommonManager*)initWithSSLCerVerification:(bool)sslCerVerification;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

微信BCWechatManager类方法简介:

/**
  * 函数名:sharedInstance
   * @param 无
   * @return 单例对象实例类
 */
+ (instancetype )sharedInstance ;
/**
  * 函数名:registWechatAppid
   * @param wechatAppID 微信开放平台的appid
   * @param universallink 上个步骤配置好的回调标识
   * @param 返回BCWechatManager实体对象
   * @return 注册微信AppID和初始化参数
 */

-(BCWechatManager*)registWechatAppid:(NSString*)wechatAppID andUniversalLink: (NSString*)universallink;


/**
   * 函数名:oauthHandleOpenURL
* @param当使用openurl回调到客户端app时候
   * @param 无
 * @return YES/NO
 */
-(BOOL)oauthHandleOpenURL:(NSURL*)url;

/**
   * 函数名:handleUniversalLink
* @param当使用universallink回调到客户端app时候
   * @param 无
   * @return YES/NO
 */

-(BOOL)handleUniversalLink:(NSUserActivity *)userActivity;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 发起微信登录

用户点击微信登录按钮,APP客户端调用IDaaS SDK的微信登录方法,代码示例如下:

//导入请求头
#import <AuthnCenter_wechat_2C/BCWechatManager.h>

//点击(触发)事件
 [[BCWechatManager sharedInstance] loginByWechatWithSuccessHandler:^(NSString * _Nonnull code, id  _Nonnull data) {
        dispatch_async(dispatch_get_main_queue(), ^{
       
        });
    }];
1
2
3
4
5
6
7
8
9

BCWechatManager对象方法简介:

/**
   * 函数名:loginByWechatWithSuccessHandler
* @param微信登录拉起
   * @param 无入参
   * @return BCWechatCompletionHandler回调,返回NSString * code,id data。1. code=0 是成功, data返回session_token和id_token
                   2.code=其他是失败,data返回原因描述。
 */

-(void)loginByWechatWithSuccessHandler:(BCWechatCompletionHandler)completionHandler;
1
2
3
4
5
6
7
8
9

BCWechatCompletionHandler回调函数返回码:

code码 说明
code=0 登录成功,此时data会返回NSDictionary: data=@{@"session_token":sessionToken内容,@"id_token":idToken内容};
code=1 登录失败,data返回字符串描述错误
code=错误码(请参考IDaaS返回码) 登录不成功,data返回错误描述
code=102 用户在微信授权页面点击取消或者拒绝授权
code=103 微信登录授权失败(微信sdk返回错误时)
Code=104 授权成功后,在绑定或者注册页面用户点击了返回按钮,用户返回取消

# UI界面定制

微信授权成功后,会根据是否匹配用户,开启绑定或者快速注册流程。在IDaaS 企业中心认证源配置中,设置新微信用户登录即注册。那么就会进行快速注册。(绑定页面还是快速注册页面显示取决于后台认证源配置)。

上图是默认UI页面。

在appdelegate 里面didFinishLaunchingWithOptions方法,设置主题对象,主题对象。代码示例:

//新建样式对象,并设置各个元素样式,如果单个元素不设置就采用上图中默认样式
BCWechatBindPhoneViewCustomSetting* settings=[[BCWechatBindPhoneViewCustomSetting alloc] init];
settings.isNavHidden=NO;
  settings.navHiddenBackButtonFrameBlock = ^CGRect(CGRect frame) {//当isNavHidden=YES的时候可以设置返回按钮的frame
            CGRect rec=CGRectMake(5, 150, 70, 40);
            return rec;
        };

    settings.navBindTitle=[[NSAttributedString alloc] initWithString:@"绑定xx"attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:18.0]}];
    settings.navRegistTitle=[[NSAttributedString alloc] initWithString:@"注册xx"attributes:@{NSForegroundColorAttributeName : UIColor.greenColor,NSFontAttributeName : [UIFont systemFontOfSize:18.0]}];
 
//    settings.navBackImage=[UIImage imageNamed:@"fanhuianniu-2"];
    settings.navColor=@"99FFCC";
    UIButton* bttn=[UIButton buttonWithType:UIButtonTypeSystem];
    [bttn setTitle:@"更多" forState:UIControlStateNormal];
    [bttn setTintColor:[UIColor blackColor]];

    [bttn addTarget:self action:@selector(clickMore) forControlEvents:UIControlEventTouchUpInside];
    settings.navRightView=bttn;
    
    settings.tileDescriptionRegistText=[[NSAttributedString alloc] initWithString:@"注册xx我的手机号"attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:25.0]}];
    settings.tileDescriptionBindText=[[NSAttributedString alloc] initWithString:@"绑定我的手机号"attributes:@{NSForegroundColorAttributeName : UIColor.greenColor,NSFontAttributeName : [UIFont systemFontOfSize:25.0]}];
    settings.descriptionRegistText=[[NSAttributedString alloc] initWithString:@"输入输入注册的手机号。。。。。。"attributes:@{NSForegroundColorAttributeName : UIColor.grayColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];
    
    settings.descriptionBindText=[[NSAttributedString alloc] initWithString:@"输入输入绑定的手机号"attributes:@{NSForegroundColorAttributeName : UIColor.redColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];
    settings.clickToSendSMSButtonText=[[NSAttributedString alloc] initWithString:@"获取验x证码"attributes:@{NSForegroundColorAttributeName : UIColor.greenColor,NSFontAttributeName : [UIFont systemFontOfSize:10.0]}];
//    settings.clickToSendBorderColor=@"CCFF33";
    settings.clickToSendSMSBackgroundImage=[UIImage imageNamed:@"wangluo"];
//    settings.countDownTextColor=@"330000";
    settings.countDownBtnBackgroundColor=@"CCCCFF";
    settings.countDownBtnBackgroundImage=[UIImage imageNamed:@"lvhang"];
    settings.confirmButtonRegistText=@"注册我";
    settings.confirmButtonBindText=@"绑定";
    settings.confirmButtonInactiveTextColor=@"FF99FF";
    settings.confirmButtonActiveTextColor=@"FF9966";
    settings.confirmButtonOnPressTextColor=@"FF66FF";
    
    settings.confirmButtonInactiveBackgroundColor=@"999999";
    settings.confirmButtonactiveBackgroundColor=@"CC00FF";
//当设置这些值之后,再用下面的类保存到内存里面。
[[BCIDABindPhoneThemeManager sharedInstance] setBindPhoneTheme:settings];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

属性列表:

属性 说明
isNavHidden Yes:隐藏导航栏,返回按钮是一个UIButton,可传入按钮图片,NO:不隐藏导航栏,返回按钮需传入一个图片。
navColor //导航栏主题色NSString,16进制,没有ox,没有#,例如:FF4F4A
navHiddenBackButtonFrameBlock 当isNavHidden=YES的时候可以设置返回按钮的frame
navBindTitle 绑定导航栏标题
navRegistTitle 注册导航栏标题
navBackImage 导航栏回退的图片,如果isNavHidden=NO,导航栏隐藏,那么就是一个单纯的在界面上回退按钮,导航栏上(50x30),无导航栏(70x40)
navRightView 导航栏右侧自定义UIview,可传入带事件的UIButton
tileDescriptionRegistText 第一标题(快速注册页面的标题),NSString
tileDescriptionBindText 第一标题(社交登录绑定号码页面的标题)
descriptionBindText 标题下面的描述字段(社交登录绑定号码页面的标题),NSString
descriptionRegistText 标题下面的描述字段(注册页面的标题)
clickToSendSMSButtonText 发送短信按钮文字
clickToSendBorderColor 发送短信按钮边框颜色NSString,16进制,没有ox,没有#,例如:FF4F4A
clickToSendSMSBackgroundColor 发送短信按钮背景颜色,NSString,16进制,没有ox,没有#,例如:FF4F4A
clickToSendSMSBackgroundImage 点击发送短信按钮背景图片设置,背景image为优先,没有设置image就用上面的背景color
countDownTextColor 发送短信倒计时的文字颜色,NSString,16进制,没有ox,没有#,例如:FF4F4A
countDownBtnBackgroundColor 发送短信倒计时背景色。NSString,16进制,没有ox,没有#,例如:FF4F4A
countDownBtnBackgroundImage 发送短信倒计时背景图片,背景image为优先,没有设置image就用上面的背景color
confirmButtonRegistText 注册,确认按钮的文字
confirmButtonBindText 绑定,确认按钮的文字
confirmButtonInactiveTextColor 确认按钮的文字不能点击时候的颜色,NSString,16进制,没有ox,没有#,例如:FF4F4A
confirmButtonActiveTextColor 确认按钮的文字可以点击时候的颜色,NSString,16进制,没有ox,没有#,例如:FF4F4A
confirmButtonOnPressTextColor 绑定,确认按钮的文字刚按下去时候的颜色,NSString,16进制,没有ox,没有#,例如:FF4F4A
confirmButtonInactiveBackgroundColor 绑定,确认按钮的背景,不能点击时候的颜色,NSString,16进制,没有ox,没有#,例如:FF4F4A
confirmButtonactiveBackgroundColor 绑定,确认按钮的背景,可以点击时候的颜色,NSString,16进制,没有ox,没有#,例如:FF4F4A

每调用一次,主题将会被覆盖,如果不设置主题,那么页面会采用默认的样式。如果只设置一部分主题,设置好的部分会被保存,没有设置的属性会采用默认的颜色样式。

# 以API的调用方式集成方法

此章节是介绍如何以API的形式接入微信登录,客户端APP需要构建绑定/注册界面。

# 调用顺序说明

  1. 项目配置。

  2. 在Appdelegate中初始化。

  3. 集成微信sdk。

  4. 拿到回调的微信授权票据code。

  5. 调用IDaaS SDK 微信登录方法。

  6. 跳转到绑定或注册页面,完成绑定或注册。

# SDK初始化

IDaaS SDK初始化方法的示例:

在appdelegate中引用头文件如下
#import <AuthnCenter_common_2C/BCIDACommonManager.h>

//在appdelegate 中的didFinishLaunchingWithOptions方法中
//1. 基本配置初始化
[[[[[BCIDACommonManager sharedInstance] initWithDomain:@"https://你的后台租户.com"] initWithClientID:@"后台租户clientID"] initWithSSLCerVerification:NO] setLogEnabled:YES] ;
1
2
3
4
5
6

# 微信登录方法

用微信授权票据登录IDaaS SDK方法示例:

//获取到微信授权登录票据code后调用
[[BCWechatApiLoginManager sharedInstance] loginWechatByCode:code andWithCallBack:^(NSString * _Nonnull code, id  _Nonnull data) {

}];
1
2
3
4

BCWechatApiLoginManager:

/**
   * 函数名:sharedInstance
   * @param 无入参
   * @return返回对象单例实例
 */
+ (instancetype )sharedInstance ;

/**
   * 函数名:loginWechatByCode
   * @param code:微信授权登录票据,从微信App回调universallink时候所带的。
   * @return BCWechatAPILoginCallBackHandler回调函数 NSString* code ,id data。
           
 */

-(void)loginWechatByCode:(NSString*)code andWithCallBack:(BCWechatAPILoginCallBackHandler)callBack;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

BCWechatAPILoginCallBackHandler回调函数总结:

成功示例1(成功匹配用户返回session_token):
code=0
data=
{
    "session_token": "btsiBjx85prcZu6I6Ki057Tmw3nSF2VO",
    "id_token":内容,
    "expire": 432000,//NSNumber类型
    "status": "SUCCESS"
}

成功示例2(返回自动注册并绑定流程,请参照3.5.3.4章节):
code=101
data=
{
    "state_token": "eyJhbGciDzKMMZtPBv2VPS8",
    "data": null,
    "status": "USER_REGISTER"
}

成功示例3(返回绑定流程,请参照3.5.3.3章节):
code=101
data=
{
    "state_token": "eyzKMMZtPBv2VPS8",
    "data": null,
    "status": " SOCIAL_BIND"
}

错误示例:
code=1
data=
{
    "error_code": "IDAAS.SDK.COMMON.1001",
    "error_msg": "Parameter X-client-id cannot be left blank."
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

如果发现程序运行报错:

请到build-settings中设置Allow Non-modular Includes In Framework Modules设置成YES。

# 绑定或注册流程方法

手机号正则验证获取国际区号

如果开启了国际号码支持 请自行先行调用国际区号获取接口,国际区号获取接口返回配置好的国际区号列表,并附有电话号码的正则表达式。下图中就是如何配置国际区号列表。

获取国际区号列表示例代码:

#import <AuthnCenter_common_2C/BCIDAInternationalPhoneCodeManager.h>


[BCIDAInternationalPhoneCodeManager getInternaltionalAreaCodeWithCompletionHandler:^(NSString * _Nonnull code, id  _Nonnull data) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        dispatch_async(dispatch_get_main_queue(), ^{
            NSDictionary* dic=(NSDictionary*)data;
        //判断电话是否符合正则表达式 
 BOOL flag=  [strongSelf parseDictionary:dic andWithMoile:mobile];
            
        });
    }];
1
2
3
4
5
6
7
8
9
10
11
12

主类方法介绍:

/**
* 函数名:getInternaltionalAreaCodeWithCompletionHandler
* @brief:获取国际区号方法
* @param 
*@param 
* @param BCSMSGetInternationalAreaCodeHandlerBlock ()结果回调函数 code=0,data返回NSDictionary的结果
**/
+(void)getInternaltionalAreaCodeWithCompletionHandler:(BCSMSGetInternationalAreaCodeHandlerBlock)resultHander;
1
2
3
4
5
6
7
8

成功示例code=0,data的值:

{
	"phoneAreaCodeDefinitions": [
		{
			"areaCode": "86",
			"displayMapping": {
				"zh-TW": "中國大陸",
				"en": "China",
				"zh-CN": "中国大陆"
			},
			"countryCode": "CN",
			"mobileRegex": "^(\\+86){0,1}\\-?1\\d{10}$",
			"areaCodeSuffixes": []
		},
		{
			"areaCode": "852",
			"displayMapping": {
				"zh-TW": "中國香港",
				"en": "Hong Kong",
				"zh-CN": "中国香港"
			},
			"countryCode": "HK",
			"mobileRegex": "^(\\+852){1}\\-?0{0,1}[1,4,5,6,7,8,9](?:\\d{7}|\\d{8}|\\d{12})$",
			"areaCodeSuffixes": []
		},
		{
			"areaCode": "886",
			"displayMapping": {
				"zh-TW": "中國臺灣",
				"en": "Taiwan",
				"zh-CN": "中国台湾"
			},
			"countryCode": "TW",
			"mobileRegex": "^(\\+886){1}\\-?[6,7,9](?:\\d{7}|\\d{8})$",
			"areaCodeSuffixes": []
		},
		{
			"areaCode": "853",
			"displayMapping": {
				"zh-TW": "中國澳門",
				"en": "Macau",
				"zh-CN": "中国澳门"
			},
			"countryCode": "MO",
			"mobileRegex": "^(\\+853){1}\\-?0{0,1}[1,4,5,6,7,8,9](?:\\d{7}|\\d{8}|\\d{12})$",
			"areaCodeSuffixes": []
		},
		{
			"areaCode": "93",
			"displayMapping": {
				"zh-TW": "阿富汗",
				"en": "Afghanistan",
				"zh-CN": "阿富汗"
			},
			"countryCode": "AF",
			"mobileRegex": "^(\\+93){1}\\-\\d{6,11}",
			"areaCodeSuffixes": []
		}
	],
	"preferredAreaCode": "CN"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

返回参数:

参数名 中文名称 类型 描述
preferredAreaCode 首选国际区号 String 当前企业中心配置的首选国际区号
countryCode 国家地区代码 String 国家地区代码
areaCode 国际电话区号 String 国际电话区号
areaCodeSuffixes 国际电话区号后缀 String 国际电话区号后缀
mobileRegex 手机号格式正则 String 手机号格式正则
displayMapping 多语言显示名映射 String 多语言显示名映射

滑块验证

  1. 手机号格式检查。

  2. 点击(触发)发送验证码事件,App客户端调用IDaaS SDK的滑块验证方法,示例如下

//导入请求头
#import <AuthnCenter_Wechat_2C/BCWechatSlideVerifyCodeManager.h>

//点击(触发)发送验证码事件
 [BCWechatSlideVerifyCodeManager startSlidingVerifyCodePageWithMobileNumber:mobile andWithResultHandler:^(NSString * _Nonnull code, id  _Nonnull data) {            
            dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"滑块验证结果==%@==%@",code,data);
            
            });
        }];
1
2
3
4
5
6
7
8
9
10

BCWechatSlideVerifyCodeManager对象方法简介:

/**
* 函数名:startSlidingVerifyCodePageWithMobileNumber
* @brief:点击拉起滑块验证
*@ param mobile手机号:带区号“+86-13800000000”或者不带区号“13800000000”都可以。
*@param complete:异步结果回调:
1.滑块校验成功时返回code=0 data=滑块token
2.code=其他 是滑块校验失败(参照错误码)
3.code=105,data=”用户关闭”是滑块框的关闭按钮被点击了
**/
+(void)startSlidingVerifyCodePageWithMobileNumber:(NSString*)mobile andWithResultHandler:(BCWechatSlideCodeHandlerBlock)resultHandler;
1
2
3
4
5
6
7
8
9
10

滑块校验code=0成功时,发送短信代码示例:

if([_status isEqualToString:@"USER_REGISTER"]){
        type=wechatSlideSMSRegist;//枚举类型
    }else if([_status isEqualToString:@"SOCIAL_BIND"]){

        type=wechatSlideSMSBind; //枚举类型
        
    }
    [BCWechatSlideVerifyCodeManager sendSMSWithSlideResultWithToken:token andMobile:mobile andWithType:type andWithCallBack:^(NSString * _Nonnull code, id  _Nonnull data) {
        if ([code isEqualToString:@"0"]) {
            NSLog(@"短信发送成功--code=%@   data=%@",code,data);
        }else{
            NSLog(@"短信发送失败--code=%@   data=%@",code,data);

        }
        
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

发送短信对象BCWechatSlideVerifyCodeManager方法简介:

/**
* 函数名:sendSMSWithSlideResultWithToken
* @brief:调用此方法发送短信,
*@ param token上个方法滑块验证成功后得到的token
*@ param mobile手机号
*@ param mobile(wechatSlideSMSSendType枚举类型)type,从微信登录方法中得到status字段,
status= SOCIAL_BIND是绑定,这里入参type=wechatSlideSMSBind
status= USER_REGISTER是注册,这里入参type=wechatSlideSMSRegist
*@param complete:异步结果回调,短信发送成功时返回code=0,code=其他 是短信发送失败,请参照IDaaS 错误码和返回的data(字符串错误描述)
**/
+(void)sendSMSWithSlideResultWithToken:(NSString*)token andMobile:(NSString*)mobile andWithType:(wechatSlideSMSSendType)type andWithCallBack:(BCWechatSendSMSHandlerBlock)callBack;
1
2
3
4
5
6
7
8
9
10
11

绑定方法

微信登录方法返回:

成功示例3(返回绑定流程):
code=101
data=
{
    "state_token": "eyJhbGciOiJIUzI1NiMZtPBv2VPS8",
    "data": null,
    "status": " SOCIAL_BIND"
}
1
2
3
4
5
6
7
8

用户收到短信验证码,填入验证码框,点击绑定按钮(或触发事件),APP客户端调用绑定方法如下:

[[BCWechatBindOrRegistManager sharedInstance] wechatBindWithMobile:手机号 andWithVerifyCode:验证码andWithStateToken: state_token andWithCompletionHandler:^(NSString * _Nonnull code, id  _Nonnull data) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;

        dispatch_async(dispatch_get_main_queue(), ^{
   //登录成功失败后处理
        });
  }];

1
2
3
4
5
6
7
8

主类BCWechatBindOrRegistManager方法简介:

/**
   * 函数名:sharedInstance
   * @param 无入参
   * @return返回对象单例实例
 */
+ (instancetype )sharedInstance ;

/**
* 函数名:wechatBindWithMobile
* @brief:微信登录后绑定方法
* @param mobile 手机号
*@param StateToken 微信登录方法获取到的state_token字段
* @param BCWechatBindCompleteHandler 登录结果回调函数
**/
-(void) wechatBindWithMobile:(NSString*)mobile andWithVerifyCode:(NSString*)verifyCode andWithStateToken: (NSString*)StateToken andWithCompletionHandler:(BCWechatBindCompleteHandler)completeHandler;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

BCWechatBindCompleteHandler回调函数返回码:

code码 说明
code=0 登录成功,data= { "session_token": "btsiBjx85prcZu6I6Ki057Tmw3nSF2VO", "id_token":内容, "expire": 432000,//NSNumber类型 "status": "SUCCESS" }
code=1 登录失败,data返回字符串描述错误
code=错误码(请参考IDaaS返回码) 登录不成功,data返回错误描述

注册并绑定方法

当微信登录方法返回:

成功示例2(返回自动注册并绑定流程):
code=101
data=
{
    "state_token": "eyJhbGciOiJIUzI1NiIsDzKMMZtPBv2VPS8",
    "data": null,
    "status": "USER_REGISTER"
}
1
2
3
4
5
6
7
8

用户收到短信验证码,填入验证码框,点击注册按钮(或触发事件),APP客户端调用注册并绑定方法如下:

[[BCWechatBindOrRegistManager sharedInstance] wechatRegistWithMobile:手机号 andWithVerifyCode:验证码andWithStateToken: state_token andWithCompletionHandler:^(NSString * _Nonnull code, id  _Nonnull data) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;

        dispatch_async(dispatch_get_main_queue(), ^{
   //登录成功失败后处理
        });
  }];

1
2
3
4
5
6
7
8

主类BCWechatBindOrRegistManager方法简介:

/**
   * 函数名:sharedInstance
   * @param 无入参
   * @return返回对象单例实例
 */
+ (instancetype )sharedInstance ;

/**
* 函数名:wechatRegistWithMobile
* @brief:微信登录后自动注册并绑定方法
* @param mobile 手机号
*@param StateToken 微信登录方法获取到的state_token字段
* @param BCWechatRegistCompleteHandler 登录结果回调函数
**/
-(void) wechatRegistWithMobile:(NSString*)mobile andWithVerifyCode:(NSString*)verifyCode andWithStateToken: (NSString*)StateToken andWithCompletionHandler:(BCWechatRegistCompleteHandler)completeHandler;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

BCWechatRegistCompleteHandler回调函数返回码:

code码 说明
code=0 登录成功,登录成功,data= { "session_token": "btsiBjx85prcZu6I6Ki057Tmw3nSF2VO", "id_token":内容, "expire": 432000,//NSNumber类型 "status": "SUCCESS" }
code=1 登录失败,data返回字符串描述错误
code=错误码(请参考IDaaS返回码) 登录不成功,data返回错误描述

# IDToken校验和获取用户信息

在登录成功后会返回session_token和id_token。id_token可以用来获取用户信息和校验登录有效期。

流程:

  1. 校验idToken
  2. 从idtoken中获取用户信息(可以不通过校验直接调用此方法)

# 校验id_token

调用示例:

  [[BCIDAIDTokenManager sharedInstance] verifySignWithIdToken:idToken andWithCallBack:^(NSString * _Nonnull code, id  _Nonnull data) {
          }];
1
2

主类BCIDAIDTokenManager介绍:

/**
   * 函数名:sharedInstance
   * @param 无入参
   * @return返回对象单例实例
*/
+ (instancetype )sharedInstance;

/**
* 函数名:verifySignWithIdToken
* @brief:校验idtoken是否在登录有效期和应用一致的方法
* @param idToken登录时候返回的
* @param BCIDAIdTokenVerifyHandlerBlock回调函数:
NSString code
id       data
**/
-(void)verifySignWithIdToken:(NSString*)idToken andWithCallBack:(BCIDAIdTokenVerifyHandlerBlock)callback;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

返回值:

code(NSString) data data的数据类型和说明
0 success [NSString]验签成功
1 错误描述 [NSString]入参为空,sdk初始化参数domain和clientID没有设置
106 时间过期 [NSString]过期的idtoken
107 clientID不符合 [NSString]可能使用了其他应用的clientID
103 验签失败 [NSString]验签过程失败
102 获取公钥为空 [NSString]验签过程中错误
见文末错误码集合 见文末错误码集合 还可能返回文末的错误码

# 从idToken解析出用户信息

调用示例:

[[BCIDAIDTokenManager sharedInstance] getUserInfoFromIdTokenWithIdToken:idToken andWithCallBack:^(NSString * _Nonnull code, id  _Nonnull data) {
            
}];
1
2
3

主类BCIDAIDTokenManager介绍:

/**
   * 函数名:sharedInstance
   * @param 无入参
   * @return返回对象单例实例
*/
+ (instancetype )sharedInstance;

/**
* 函数名:getUserInfoFromIdTokenWithIdToken
* @brief:从idToken解析用户信息
* @param idToken登录返回的
* @param BCIDAIdTokenGetInfoHandlerBlock回调函数:
NSString code
id       data

**/
-(void)getUserInfoFromIdTokenWithIdToken:(NSString*)idToken andWithCallBack:(BCIDAIdTokenGetInfoHandlerBlock)callback;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

用户信息参数说明:

参数名 描述
iss 令牌签发人
aud 令牌接收者,应用的clientId
exp 令牌的过期时间
jti 令牌的id
iat 令牌的签发时间
sub 固定为subject
name 用户姓名
mobile 用户手机号
id 用户的id
userName 用户名
email 用户邮箱

回调函数返回值:

成功示例:
code=0
data=
{
	"id": "20220729174957176-2C7F-A2C54C293",
	"exp": 1659407592,
	"nbf": 1659407172,
	"mobile": "+86-13808603636",
	"jti": "7iwCYPo8EYcmLAD18x-CAw",
	"iss": "https:\/\/sdk2c.idaas-test-alpha.bccastle.com\/api\/v1\/oauth2",
	"userName": "zhangrui1",
	"sub": "20220729174957176-2C7F-A2C54C293",
	"aud": "S1ScicdIVR1QUbNs8TBz6BYVd2Zt8Adc",
	"iat": 1659407292,
	"email": "",
	"name": "zhangrui1"
}

失败示例
code=102
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 刷新IDToken

调用示例:

[[BCIDAIDTokenRefreshManager sharedInstance] refreshIdTokenWithSessionToken:sessionToken andWithCallBack:^(NSString * _Nonnull code, id  _Nonnull data) {
            NSString* jsonS=(NSString*)data;
         NSDictionary* dict=  [self dictionaryWithJsonString:jsonS];//解析jsonStr到NSDictionary
          NSString* idTok= [dict objectForKey:@"id_token"];
            NSString* session_tok=[dict objectForKey:@"session_token"];
            NSString* expr=[dict objectForKey:@"expire"];
                  }];
1
2
3
4
5
6
7

主类BCIDAIDTokenManager介绍:

/**
   * 函数名:sharedInstance
   * @param 无入参
   * @return返回对象单例实例
*/
+ (instancetype )sharedInstance;

/**
* 函数名:refreshIdTokenWithSessionToken
* @brief:刷新idToken
* @param sessionToken登录返回的
* @param BCIDAIdTokenRefreshIDTokenHandlerBlock回调函数:
NSString code
id       data

**/
-(void)refreshIdTokenWithSessionToken:(NSString*)sessionToken andWithCallBack:(BCIDAIdTokenRefreshIDTokenHandlerBlock)callBack;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

回调函数返回值:

成功示例:
code=0
data=
{
  "id_token" : "eyJraWQiOiJhODJkzJjLmlkYWFzLXRllKp6w",
  "session_token" : "apcOKuyry7kASh9h6mtf2G2GbettkyiU",
  "expire" : 7200
}
1
2
3
4
5
6
7
8

# 返回码

状态码 错误码 (error_code) 错误说明 (error_msg) 处理措施
400 IDAAS.SDK.COMMON.1001 Parameter {0} cannot be left blank
参数 {0} 不能为空
400 IDAAS.SDK.COMMON.1002 The {0} parameter format is incorrect
参数 {0} 格式错误
400 IDAAS.SDK.COMMON.1003 Device information is incomplete
设备信息不完整
400 IDAAS.SDK.COMMON.1004 Signature decryption error
签名解密错误
400 IDAAS.SDK.COMMON.1005 The {0} has failed
{0} 已失效
400 IDAAS.SDK.COMMON.1006 The {0} parameter error
{0} 参数错误
400 IDAAS.SDK.COMMON.1007 The {0} parameter type error
{0}参数类型错误
500 IDAAS.SDK.COMMON.1008 The system is busy. Try again later
系统繁忙。稍后再试
400 IDAAS.SDK.COMMON.1009 Unknown authentication configuration
未知的认证配置
400 IDAAS.SDK.COMMON.1010 Failed to obtain the enterprise center global configuration
获取企业中心全局配置失败
400 IDAAS.SDK.COMMON.1011 Failed to obtain the international area code configuration
获取国际区号配置失败
400 IDAAS.SDK.COMMON.1012 The x-client-ID is incorrect and the corresponding application cannot be found
X-client-id错误,找不到对应的应用
400 IDAAS.SDK.COMMON.1013 The corresponding user is not found
未找到对应的用户
400 IDAAS.SDK.COMMON.1014 Application private key not found
未找到应用私钥
400 IDAAS.SDK.LOGIN.1001 Error calling interface {0}
调用 {0} 接口出错
400 IDAAS.SDK.LOGIN.1002 User not bound
用户未绑定
400 IDAAS.SDK.LOGIN.1003 The user has been locked due to too many unsuccessful login attempts. It will be unlocked in {0} minutes and {1} seconds
由于多次登录失败,用户已被锁定。 它将在 {0} 分钟和 {1} 秒内解锁
400 IDAAS.SDK.LOGIN.1004 Failed to obtain the password policy
获取密码策略错误
400 IDAAS.SDK.LOGIN.1005 Invalid username or password. Remaining login attempts: {0}
无效的用户名或密码。 其余登录尝试次数:{0}
400 IDAAS.SDK.LOGIN.1006 Configuration error, unable to find wechat authentication source
配置错误,找不到微信认证源
400 IDAAS.SDK.LOGIN.1007 Configuration error, unable to find alipay authentication source
配置错误,找不到支付宝认证源
400 IDAAS.SDK.LOGIN.1008 The configuration is incorrect. The one-click login authentication source cannot be found
配置错误,无法找到一键登录认证源
400 IDAAS.SDK.SMS.1001 {0} slide base map is not initialized successfully, please check the path
{0} 滑动底图未初始化成功,请检查路径
400 IDAAS.SDK.SMS.1002 {0} verification code coordinate resolution failed
{0} 验证码坐标解析失败
400 IDAAS.SDK.SMS.1003 {0} verification code coordinate verification fails
{0} 验证码坐标校验失败
400 IDAAS.SDK.SMS.1004 The graphic verification code is incorrect
图形验证码校验错误
400 IDAAS.SDK.SMS.1005 SMS verification code verification is incorrect
短信验证码验证错误
400 IDAAS.SDK.SMS.1006 The email verification code is incorrect
邮件验证码验证错误
400 IDAAS.SDK.SMS.1007 Sending scenario does not exist
发送场景不存在
400 IDAAS.SDK.SMS.1008 Failed to send the verification code
发送验证码失败
400 IDAAS.SDK.SOCIAL.1001 The social account is unbound incorrectly
社交账号解绑错误
400 IDAAS.SDK.SOCIAL.1002 The social account has been bound, please unbind it first
社交账号已绑定,请先解绑
400 IDAAS.SDK.PWD.1001 The password length is incorrect
密码长度错误
400 IDAAS.SDK.PWD.1002 The password cannot be the username
密码不能为用户名
400 IDAAS.SDK.PWD.1003 Your password complexity is low
你的密码复杂度过低
400 IDAAS.SDK.PWD.1004 The password is weak
密码很弱
400 IDAAS.SDK.PWD.1005 The password is used before, cannot be used again
该密码已被使用过,不能再次使用
400 IDAAS.SDK.PWD.1006 Password cannot username in reverse order
密码不能是用户名的倒序
400 IDAAS.SDK.PWD.1007 The number of repeated password characters exceeded the upper limit
密码重复字符数超过限制
400 IDAAS.SDK.PWD.1008 Password cannot contain :username, phone number, email prefix, name in PinYing
密码不能包含:用户名、电话号码、邮件前缀、拼音名
400 IDAAS.SDK.MFA.1001 The mobile doesn't match the user
手机号和用户不匹配
400 IDAAS.SDK.MFA.1002 The access control policy is incorrect
访问控制策略配置错误
400 IDAAS.SDK.MFA.1003 Access control authentication source type conversion error
访问控制身份验证源类型转换错误