QQ Login
Document Overview
This document describes how to integrate QQ authorized login into an iOS client. When the user taps the QQ login button in the client App, the BambooCloud IDaaS SDK launches the authorization page in the QQ App. After the user taps the Authorize Login button and authorization succeeds, the QQ App returns to the client App. The BambooCloud IDaaS SDK then automatically receives the temporary authorization code, takes it to the BambooCloud IDaaS server for authentication, and returns the final authentication result to the client App.
Process Overview
Login Flow

Integration Flow
- The user taps the QQ login button in the App client.
- The App client calls the BambooCloud IDaaS SDK QQ login method.
- The BambooCloud IDaaS SDK calls the QQ SDK login method.
- The QQ SDK launches the QQ App on the phone and displays the authorization login page.
- The user taps the Authorize Login button.
- QQ authorization succeeds. The QQ App returns to the client App with the QQ authorization code. The BambooCloud IDaaS SDK automatically obtains the QQ authorization code during the launch.
- BambooCloud IDaaS requests authentication from the BambooCloud IDaaS server using the QQ authorization code.
- The BambooCloud IDaaS server checks whether a mobile number is bound. If a mobile number is already bound, the BambooCloud IDaaS server authentication succeeds and returns
sessionTokenandid_tokento the BambooCloud IDaaS SDK. - The BambooCloud IDaaS SDK returns
sessionTokenandid_tokento the App client. - If the BambooCloud IDaaS server finds that no mobile number is bound, it returns a flag indicating that binding or registration is required.
- The BambooCloud IDaaS server displays the binding or registration page.
- The user enters a mobile number, taps Get Verification Code, and completes the slider captcha.
- The BambooCloud IDaaS SDK takes the slider captcha code to the BambooCloud IDaaS server to request slider verification.
- The BambooCloud IDaaS server validates the slider successfully and returns a token to the BambooCloud IDaaS SDK.
- The BambooCloud IDaaS SDK uses the token and mobile number to request that the BambooCloud IDaaS server send an SMS verification code.
- The user receives the SMS verification code, enters it in the input box, and taps the Bind or Register button.
- The BambooCloud IDaaS SDK submits the binding or login data to the BambooCloud IDaaS server.
- After binding or registration succeeds, the BambooCloud IDaaS server returns
sessionTokenandid_tokento the BambooCloud IDaaS SDK. - The BambooCloud IDaaS SDK returns
sessionTokenandid_tokento the client App. - The client can use
id_tokento verify login validity and obtain basic user information. - The client can use
session_tokento refreshid_token.
Prerequisites
Create an Application on QQ Open Platform
Developers log in to QQ Open Platform, create a developer account, and follow the official documentation to create a new application and wait for approval.
Obtain the App clientID
Log in to the BambooCloud IDaaS Enterprise Center, choose Resources > Applications, and click the application that belongs to you to view the clientID.

Configure the Authentication Source
Log in to the BambooCloud IDaaS Enterprise Center, choose Authentication > Authentication Source Management > QQ.

Click Add Authentication Source, enter the AppKey and AppSecret obtained after registering the application on the QQ development platform, set the channel to Mobile Application, and enter a display name.

Switch to Resources > Applications, find the newly created application, and go to Login Configuration > Mobile Application > Configure.

Find the QQ configuration and turn it on to complete the authentication source configuration.

Add Dependencies
Add Tencent's packages to your project.
TencentOpenAPI.framework //QQ SDK package
TencentOpenApi_IOS_Bundle.bundleNote: TencentOpenAPI.framework and TencentOpenApi_IOS_Bundle.bundle must be placed in the root directory of the application's resources; otherwise, resources may fail to load.
Add Main Libraries
AuthnCenter_common_2C.framework
AuthnCenter_QQ_2C.framework
AuthnCenter_QQ_2C.bundle // Resource bundleDrag the BambooCloud IDaaS SDK into your project and import it as shown below:

Also add the following Pod dependency:
pod 'JWT', '~> 3.0.0-beta.14'Targets Configuration
- Add the system libraries required by the QQ SDK as follows.
AuthnCenter_common_2C.framework //BambooCloud IDaaS SDK, current version 1.5.0
AuthnCenter_QQ_2C.framework // BambooCloud IDaaS SDK, current version 1.5.0
AuthnCenter_QQ_2C.bundle // Resource bundle, current version 1.5.0Set Other Linker Flags. In your project file, select Build Settings, and add
-ObjC -all_load -fobjc-arcto Other Linker Flags.
Set the URL scheme. In Xcode, select your project settings, choose the TARGETS section, and in the Info tab under URL Types, add a URL scheme with your registered application ID (as shown below). The URL Schemes should be
tencent+ your Tencent application appid.
In Xcode, select your project settings, choose the TARGETS section, and in the Info tab under LSApplicationQueriesSchemes, add
mqqopensdkapiV2andmqq(as shown below).
Set bitcode to NO.

UniversalLink Configuration
After authorization succeeds, the App client needs to be launched. Configure
universallinkby referring to online tutorials.For how to configure
universalin the QQ App, refer to https://wiki.connect.qq.com/填写及校验universallinks.After
universallinkis configured successfully, enter it in the App client. Add Associated Domains as shown below and enter theuniversallinkin the format shown below.
The universal link format is:
applinks:your-universallink.Set Allow Non-modular Includes In Framework Modules to Yes.

Development Integration
Built-in UI Integration
This section describes one-time QQ login launch in the App client. The App client only needs to integrate the BambooCloud IDaaS SDK initialization method and QQ registration method, and call the BambooCloud IDaaS SDK QQ login method where QQ login needs to be launched. The remaining authentication, registration, and binding UI flows are fully provided by the BambooCloud IDaaS SDK. After successful login, sessionToken and IDToken are returned in the callback.
Before this section, complete all Xcode configurations and QQ Open Platform configurations in the previous chapter.
SDK Initialization
The BambooCloud IDaaS SDK provides an initialization method in which you can specify the tenant, clientID, and whether to enable log output.
Initialization example:
Reference the following headers in AppDelegate:
#import <AuthnCenter_common_2C/BCIDACommonManager.h>
#import <AuthnCenter_QQ_2C/BCQQLoginManager.h>
#import <TencentOpenAPI/TencentOpenApiUmbrellaHeader.h>
//Initialize in didFinishLaunchingWithOptions
[[[[[BCIDACommonManager sharedInstance] initWithDomain:@"https://your-backend-tenant.com"] initWithClientID:@"your-tenant-clientID"] initWithSSLCerVerification:NO] setLogEnabled:YES] ;
[[BCQQLoginManager sharedInstance] registQQAppid:@"1110072246" andUniversalLink:@"https://b2.bccastle.com/qq_conn/1110072246"];In AppDelegate, the following methods receive the QQ scheme callback.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
[[BCQQLoginManager sharedInstance] handleOpenUrl:url];
return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
[[BCQQLoginManager sharedInstance] handleOpenUrl:url];
return YES;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
[[BCQQLoginManager sharedInstance] handleOpenUrl:url];
return YES;
}
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler{
[[BCQQLoginManager sharedInstance] handleUniversalLink:userActivity];
return YES;
}Main methods of the basic configuration initialization class BCIDACommonManager:
/**
* Method name: sharedInstance
* @param none
* @return singleton instance
*/
+ (instancetype )sharedInstance ;
/**
* Method name: initWithDomain
* @param domain, starts with https:// and ends with .com.
* @return instance
*/
-(BCIDACommonManager)initWithDomain:(NSString)domain
/**
* Method name: initWithClientID
* @param client id.
* @return instance
*/
-(BCIDACommonManager)initWithClientID:(NSString)clientID;
/**
* Method name: setLogEnabled
* @param boolean indicating whether to enable logs.
* @return instance
*/
-(void)setLogEnabled:(BOOL)enable;
/**
* Method name: initWithSSLCerVerification
* @param boolean indicating whether SSL certificate verification is enabled.
* @return instance
*/
-(BCIDACommonManager*)initWithSSLCerVerification:(bool)sslCerVerification;BCQQLoginManager method overview:
/**
* Method name: sharedInstance
* @param none
* @return singleton instance
*/
+ (instancetype )sharedInstance ;
/**
* Method name: registQQAppid
* @param QQAppid QQ Open Platform appid
* @param universalLink universalLink configured on QQ Open Platform
*@return singleton instance
*/
-(BCQQLoginManager*)registQQAppid:(NSString*)QQAppid andUniversalLink:(NSString*)universalLink;
/**
* Method name: handleOpenUrl
* @param call this method when the QQ app returns to the client app (called in openUrl method)
* @param none
* @return YES/NO
*/
-(BOOL)handleOpenUrl:(NSURL*)url;
/**
* Method name: handleUniversalLink
* @param call this method when the QQ app returns to the client app (called in the universal link receiving method)
* @param none
* @return YES/NO
*/
-(BOOL)handleUniversalLink:(NSUserActivity *)userActivity;Launch QQ Login
When the user taps the QQ login button, the App client calls the BambooCloud IDaaS SDK QQ login method as shown below:
//Import headers
#import <AuthnCenter_Alipay_2C/BCQQLoginManager.h>
#import <TencentOpenAPI/TencentOpenApiUmbrellaHeader.h>
//Triggered event
[[BCQQLoginManager sharedInstance] loginQQWithCallBack:^(NSString * _Nonnull code, id _Nonnull data) {
dispatch_async(dispatch_get_main_queue(), ^{
});
}];BCQQLoginManager login method overview:
/**
* Method name: loginQQWithCallBack
* @param launch QQ login
* @param
* @return BCQQLoginCompletionHandler callback.
1.code=0 means success, data returns sessionToken and IDToken
2.code=other means failure, data returns reason description.
*/
-(void)loginQQWithCallBack:(BCQQLoginCompletionHandler)callBack;BCQQLoginCompletionHandler callback codes:
| Code | Description |
|---|---|
| code=0 | Login succeeded. data returns an NSDictionary containing: data=@{@"session_token": session_tokenValue,@"id_token":idTokenValue}; |
| code=1 | Login failed. data returns a string describing the error, usually a non-interface-request error such as missing parameters. |
| code= 102 | QQ app authorization failed |
| code=103 | Cancel login was tapped on the QQ app authorization page |
| code=104 | After QQ authorization succeeded, the user tapped the back button on the bind/register mobile number page and canceled. |
| code=error code (refer to BambooCloud IDaaS return codes) | Login unsuccessful. data returns an error description and interface error code. |
UI Customization

After QQ authorization succeeds, depending on whether the user is matched, the binding or quick registration flow is started. In the BambooCloud IDaaS Enterprise Center authentication source configuration, set new QQ users to register automatically on login, and quick registration will be performed. (Whether the binding page or the quick registration page is displayed depends on the backend authentication source configuration.)

The above figure shows the default UI page.
In AppDelegate, in the didFinishLaunchingWithOptions method, set the theme object.
Example code:
//Create a style object and set the style of each element. If an individual element is not set, the default style shown above is used.
BCQQBindPhoneViewCustomSetting* settings=[[BCQQBindPhoneViewCustomSetting alloc] init];
settings.isNavHidden=NO;
// settings.hideInternationalPhoneCodeArea=YES;
settings.navHiddenBackButtonFrameBlock = ^CGRect(CGRect frame) {//When isNavHidden=YES, you can set the frame of the back button
CGRect rec=CGRectMake(5, 150, 70, 40);
return rec;
};
settings.navBindTitle=[[NSAttributedString alloc] initWithString:@"Bind xx"attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:18.0]}];
settings.navRegistTitle=[[NSAttributedString alloc] initWithString:@"Register xx"attributes:@{NSForegroundColorAttributeName : UIColor.greenColor,NSFontAttributeName : [UIFont systemFontOfSize:18.0]}];
settings.navBackImage=[UIImage imageNamed:@"backbutton-2"];
settings.navColor=@"99FFCC";
UIButton* bttn=[UIButton buttonWithType:UIButtonTypeSystem];
[bttn setTitle:@"More" forState:UIControlStateNormal];
[bttn setTintColor:[UIColor blackColor]];
[bttn addTarget:self action:@selector(clickMore) forControlEvents:UIControlEventTouchUpInside];
settings.navRightView=bttn;
settings.tileDescriptionRegistText=[[NSAttributedString alloc] initWithString:@"Register xx with my mobile number"attributes:@{NSForegroundColorAttributeName : UIColor.orangeColor,NSFontAttributeName : [UIFont systemFontOfSize:25.0]}];
settings.tileDescriptionBindText=[[NSAttributedString alloc] initWithString:@"Bind my mobile number"attributes:@{NSForegroundColorAttributeName : UIColor.greenColor,NSFontAttributeName : [UIFont systemFontOfSize:25.0]}];
settings.descriptionRegistText=[[NSAttributedString alloc] initWithString:@"Enter the mobile number to register..."attributes:@{NSForegroundColorAttributeName : UIColor.grayColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];
settings.descriptionBindText=[[NSAttributedString alloc] initWithString:@"Enter the mobile number to bind..."attributes:@{NSForegroundColorAttributeName : UIColor.redColor,NSFontAttributeName : [UIFont systemFontOfSize:16.0]}];
settings.clickToSendSMSButtonText=[[NSAttributedString alloc] initWithString:@"Get verification code"attributes:@{NSForegroundColorAttributeName : UIColor.greenColor,NSFontAttributeName : [UIFont systemFontOfSize:10.0]}];
// settings.clickToSendBorderColor=@"CCFF33";
settings.clickToSendSMSBackgroundImage=[UIImage imageNamed:@"network"];
// settings.countDownTextColor=@"330000";
settings.countDownBtnBackgroundColor=@"CCCCFF";
settings.countDownBtnBackgroundImage=[UIImage imageNamed:@"greenbank"];
settings.confirmButtonRegistText=@"Register me";
settings.confirmButtonBindText=@"Bind";
settings.confirmButtonInactiveTextColor=@"FF99FF";
settings.confirmButtonActiveTextColor=@"FF9966";
settings.confirmButtonOnPressTextColor=@"FF66FF";
settings.confirmButtonInactiveBackgroundColor=@"999999";
settings.confirmButtonactiveBackgroundColor=@"CC00FF";
// settings.confirmButtonInactiveBackgroundImage=[UIImage imageNamed:@"24gf-stopCircle"];
// settings.confirmButtonActiveBackgroundImage=[UIImage imageNamed:@"24gf-stopCircle-2"];
//After setting these values, save them to memory using the following class.
[[BCAlipayBindPhoneThemeManager sharedInstance] setBindPhoneTheme:settings];Property list:
| Property | Description |
|---|---|
| isNavHidden | YES: hides the navigation bar; the back button is a UIButton and an image can be passed. NO: does not hide the navigation bar; an image must be passed for the back button. |
| navColor | Navigation bar theme color, NSString, hex format, without 0x or #, e.g. FF4F4A |
| navHiddenBackButtonFrameBlock | When isNavHidden=YES, you can set the frame of the back button. |
| navBindTitle | Navigation bar title for binding |
| navRegistTitle | Navigation bar title for registration |
| navBackImage | Navigation bar back image. If isNavHidden=NO, the navigation bar is not hidden, and it is a simple back button on the interface. On the navigation bar (50x30), without navigation bar (70x40). |
| navRightView | Custom UIView on the right side of the navigation bar; a UIButton with events can be passed. |
| tileDescriptionRegistText | First title (title of the quick registration page), NSString. |
| tileDescriptionBindText | First title (title of the social login bind number page). |
| descriptionBindText | Description field below the title (title of the social login bind number page), NSString. |
| descriptionRegistText | Description field below the title (title of the registration page). |
| clickToSendSMSButtonText | Text of the send SMS button |
| clickToSendBorderColor | Border color of the send SMS button, NSString, hex format, without 0x or #, e.g. FF4F4A. |
| clickToSendSMSBackgroundColor | Background color of the send SMS button, NSString, hex format, without 0x or #, e.g. FF4F4A. |
| clickToSendSMSBackgroundImage | Background image of the send SMS button; image takes precedence, otherwise the background color above is used. |
| countDownTextColor | Text color of the SMS countdown, NSString, hex format, without 0x or #, e.g. FF4F4A. |
| countDownBtnBackgroundColor | Background color of the SMS countdown button, NSString, hex format, without 0x or #, e.g. FF4F4A. |
| countDownBtnBackgroundImage | Background image of the SMS countdown button; image takes precedence, otherwise the background color above is used. |
| confirmButtonRegistText | Text of the registration confirm button |
| confirmButtonBindText | Text of the binding confirm button |
| confirmButtonInactiveTextColor | Text color of the confirm button when it cannot be tapped, NSString, hex format, without 0x or #, e.g. FF4F4A. |
| confirmButtonActiveTextColor | Text color of the confirm button when it can be tapped, NSString, hex format, without 0x or #, e.g. FF4F4A. |
| confirmButtonOnPressTextColor | Text color of the confirm button when just pressed, NSString, hex format, without 0x or #, e.g. FF4F4A. |
| confirmButtonInactiveBackgroundColor | Background color of the confirm button when it cannot be tapped, NSString, hex format, without 0x or #, e.g. FF4F4A. |
| confirmButtonactiveBackgroundColor | Background color of the confirm button when it can be tapped, NSString, hex format, without 0x or #, e.g. FF4F4A. |
Each call overwrites the theme. If no theme is set, the page uses the default style. If only part of the theme is set, the set parts are saved and unset properties use the default colors and styles.
API-based Integration
This section describes how to integrate QQ login in API form. The client App needs to build its own binding/registration UI.
Call Sequence
Project configuration.
Initialize in
AppDelegate.Integrate the QQ login SDK.
Obtain the QQ authorization code, access token, and openid from the callback.
Call the BambooCloud IDaaS SDK QQ login method.
Navigate to the binding or registration page and complete binding or registration.
SDK Initialization
BambooCloud IDaaS SDK initialization example:
Reference the following headers in AppDelegate:
#import <AuthnCenter_common_2C/BCIDACommonManager.h>
//Initialize in didFinishLaunchingWithOptions
[[[[[BCIDACommonManager sharedInstance] initWithDomain:@"https://your-backend-tenant.com"] initWithClientID:@"your-tenant-clientID"] initWithSSLCerVerification:NO] setLogEnabled:YES] ;QQ Login Method
Example of logging in to the BambooCloud IDaaS SDK with the QQ authorization code:
//Call after obtaining the QQ authorization login code
[[BCQQAPILoginManager sharedInstance] loginQQByAccessToken:accessToken andOpenID:openID andWithCallBack:^(NSString * _Nonnull code, id _Nonnull data) {
}];BCQQAPILoginManager:
/**
* Method name: sharedInstance
* @param none
* @return singleton instance
*/
+ (instancetype )sharedInstance ;
/**
* Method name: loginQQByAccessToken
* @param accessToken: accessToken obtained from QQ authorized login [required].
* @param openid: openID obtained from QQ authorized login [required].
* @return BCQQAPILoginCallBackHandler callback `NSString* code, id data`.
*/
-(void)loginQQByAccessToken:(NSString*)accessToken andOpenID:(NSString*)openid andWithCallBack: (BCQQAPILoginCallBackHandler)callBack;BCQQAPILoginCallBackHandler callback summary:
Success example 1 (user matched, returns session_token):
code=0
data=
{
"session_token": "btsiBjx85prcZu6I6Ki057Tmw3nSF2VO",
"id_token": value
"expire": 432000,//NSNumber
"status": "SUCCESS"
}
Success example 2 (returns auto-registration and binding flow):
code=101
data=
{
"state_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ7XCJzb2NpYWxVaWRcIjpcIm8zRHVFNVNySXVodTlIZHFucHd0c3Y5a2dkSFFcIixcInN0YXR1c1wiOlwiVVNFUl9SRUdJU1RFUlwifSIsImV4cCI6MTY0NjcwNTcwNCwiaWF0IjoxNjQ2NzAzOTA0LCJqdGkiOiIxNjQ2NzAzOTA0NTEwMCJ9.tLEpS-9jrXwiJI3GlZw4RGg_z0zMDzKMMZtPBv2VPS8",
"data": "{\"socialBindOrRegisterFlow\":[\"VERIFY_PHONE\",\"VERIFY_EMAIL\"]}",
"status": "USER_REGISTER"
}
Success example 3 (returns binding flow):
code=101
data=
{
"state_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ7XCJzb2NpYWxVaWRcIjpcIm8zRHVFNVNySXVodTlIZHFucHd0c3Y5a2dkSFFcIixcInN0YXR1c1wiOlwiVVNFUl9SRUdJU1RFUlwifSIsImV4cCI6MTY0NjcwNTcwNCwiaWF0IjoxNjQ2NzAzOTA0LCJqdGkiOiIxNjQ2NzAzOTA0NTEwMCJ9.tLEpS-9jrXwiJI3GlZw4RGg_z0zMDzKMMZtPBv2VPS8",
"data": "{\"socialBindOrRegisterFlow\":[\"VERIFY_PHONE\",\"VERIFY_EMAIL\"]}",
"status": " SOCIAL_BIND"
}
Error example:
code=1
data=
{
"error_code": "IDAAS.SDK.COMMON.1001",
"error_msg": "Parameter X-client-id cannot be left blank."
}Login-Triggered Registration Flow
Mobile number regular expression and international area codes
If international number support is enabled, call the international area code API first. The API returns the configured list of international area codes along with regular expressions for phone numbers. The figure below shows how to configure the international area code list.

Example code for obtaining the international area code list:
#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;
//Check whether the number matches the regular expression
BOOL flag= [strongSelf parseDictionary:dic andWithMoile:mobile];
});
}];Main method overview:
/**
* Method name: getInternaltionalAreaCodeWithCompletionHandler
* @brief: Get international area codes
* @param
*@param
* @param BCSMSGetInternationalAreaCodeHandlerBlock () result callback. code=0, data returns an NSDictionary
**/
+(void)getInternaltionalAreaCodeWithCompletionHandler:(BCSMSGetInternationalAreaCodeHandlerBlock)resultHander;Success example when code=0, value of data:
{
"phoneAreaCodeDefinitions": [
{
"areaCode": "86",
"displayMapping": {
"zh-TW": "Mainland China",
"en": "China",
"zh-CN": "Mainland China"
},
"countryCode": "CN",
"mobileRegex": "^(\\+86){0,1}\\-?1\\d{10}$",
"areaCodeSuffixes": []
},
{
"areaCode": "852",
"displayMapping": {
"zh-TW": "Hong Kong",
"en": "Hong Kong",
"zh-CN": "Hong Kong"
},
"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": "Taiwan",
"en": "Taiwan",
"zh-CN": "Taiwan"
},
"countryCode": "TW",
"mobileRegex": "^(\\+886){1}\\-?[6,7,9](?:\\d{7}|\\d{8})$",
"areaCodeSuffixes": []
},
{
"areaCode": "853",
"displayMapping": {
"zh-TW": "Macau",
"en": "Macau",
"zh-CN": "Macau"
},
"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": "Afghanistan",
"en": "Afghanistan",
"zh-CN": "Afghanistan"
},
"countryCode": "AF",
"mobileRegex": "^(\\+93){1}\\-\\d{6,11}",
"areaCodeSuffixes": []
}
],
"preferredAreaCode": "CN"
}Returned parameters:
| Parameter | Name | Type | Description |
|---|---|---|---|
| preferredAreaCode | Preferred area code | String | Preferred international area code configured in the Enterprise Center |
| countryCode | Country/region code | String | Country/region code |
| areaCode | International dialing code | String | International dialing code |
| areaCodeSuffixes | International dialing code suffixes | String | International dialing code suffixes |
| mobileRegex | Mobile number format regular expression | String | Mobile number format regular expression |
| displayMapping | Multilingual display name mapping | String | Multilingual display name mapping |
Slider Verification
Before calling this method, perform a mobile number format check.
When the send verification code event is triggered, the App client calls the BambooCloud IDaaS SDK slider verification method as shown below:
//Import header
#import <AuthnCenter_QQ_2C/BCQQSlideVerifyCodeManager.h>
//Triggered event
[BCQQSlideVerifyCodeManager startSlidingVerifyCodePageWithMobileNumber:mobile andWithResultHandler:^(NSString * _Nonnull code, id _Nonnull data){
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Slider verification result==%@==%@",code,data);
});
}];BCQQSlideVerifyCodeManager method overview:
/**
* Method name: startSlidingVerifyCodePageWithMobileNumber
* @brief: Launch the slider captcha
*@ param mobile: mobile number with area code, e.g. "+86-13800000000", or without area code, e.g. "13800000000".
*@param BCQQSlideCodeHandlerBlock: asynchronous result callback:
1. When slider verification succeeds, returns code=0 and data=slider token.
2. code=other means slider verification failed (refer to error codes).
3. code=105 and data="User closed" means the close button of the slider box was tapped.
**/
+(void)startSlidingVerifyCodePageWithMobileNumber:(NSString*)mobile andWithResultHandler:(BCQQSlideCodeHandlerBlock)resultHandler;When slider verification succeeds with code=0, example code for sending an SMS:
QQSlideSMSSendType type=0;
if([_status isEqualToString:@"USER_REGISTER"]){
type=qqSlideSMSRegist;
}else if([_status isEqualToString:@"SOCIAL_BIND"]){
type=qqSlideSMSBind;
}
[BCQQSlideVerifyCodeManager sendSMSWithSlideResultWithToken:token andMobile:mobile andWithType:type andWithCallBack:^(NSString * _Nonnull code, id _Nonnull data) {
if ([code isEqualToString:@"0"]) {
NSLog(@"SMS sent successfully--code=%@ data=%@",code,data);
}else{
NSLog(@"SMS failed to send--code=%@ data=%@",code,data);
}
}];BCQQSlideVerifyCodeManager SMS sending method overview:
/**
* Method name: sendSMSWithSlideResultWithToken
* @brief: Call this method to send an SMS.
*@ param token: token obtained after slider verification succeeds in the previous method.
*@ param mobile: mobile number.
*@ param type: `qqSlideSMSSendType` enum, obtained from the `status` field of the login method.
status= SOCIAL_BIND means binding, so pass type=qqSlideSMSBind.
status= USER_REGISTER means registration, so pass type=qqSlideSMSRegist.
*@param complete: asynchronous result callback. SMS sent successfully returns code=0; other codes mean SMS sending failed. Refer to BambooCloud IDaaS error codes and the returned data (string error description).
**/
+(void)sendSMSWithSlideResultWithToken:(NSString*)token andMobile:(NSString*)mobile andWithType:(QQSlideSMSSendType)type andWithCallBack:(BCQQSendSMSHandlerBlock)callBack;Binding Method
When the QQ login method returns:
Success example (returns binding flow):
code=101
data=
{
"state_token": "eyJhbGciEwMCJ9.tLEpS-9jrXwiJI3GlZw4RGPBv2VPS8",
"data": "{\"socialBindOrRegisterFlow\":[\"VERIFY_PHONE\",\"VERIFY_EMAIL\"]}",
"status": " SOCIAL_BIND"
}After the user receives the SMS verification code, enters it in the input box, and taps the Bind button (or triggers the event), the App client calls the binding method as shown below:
Example code:
[[BCQQBindOrRegistManager sharedInstance] qqBindWithMobile:mobile andWithVerifyCode:verifyCode andWithStateToken:_state_token andWithCompletionHandler:^(NSString * _Nonnull code, id _Nonnull data) {
}];Main methods of BCQQBindOrRegistManager:
/**
* Method name: sharedInstance
* @param none
* @return singleton instance
*/
+ (instancetype )sharedInstance ;
/**
* Method name: qqBindWithMobile
* @brief: Binding method after QQ login
* @param mobile mobile number
*@param StateToken `state_token` field obtained from the login method
*@param verifyCode SMS verification code
* @param BCQQBindCompleteHandler callback
**/
-(void)qqBindWithMobile:(NSString*)mobile andWithVerifyCode:(NSString*)verifyCode andWithStateToken: (NSString*)StateToken andWithCompletionHandler:(BCQQBindCompleteHandler)completeHandler;BCQQBindCompleteHandler callback codes:
| Code | Description |
|---|---|
| code=0 | Login succeeded. data= { "session_token": "btsiBjx85prcZu6I6Ki057Tmw3nSF2VO", "id_token": value, "expire": 432000,//NSNumber "status": "SUCCESS" } |
| code=1 | Login failed. data returns a string describing the error. |
| code=error code (refer to BambooCloud IDaaS return codes) | Login unsuccessful. data returns an error description. |
Registration Method
When the QQ login method returns:
Success example (returns auto-registration and binding flow):
code=101
data=
{
"state_token": "eyJhbGciOiJIUzI1N_z0zMDzKMMZtPBv2VPS8",
"data": "{\"socialBindOrRegisterFlow\":[\"VERIFY_PHONE\",\"VERIFY_EMAIL\"]}",
"status": "USER_REGISTER"
}After the user receives the SMS verification code, enters it in the input box, and taps the Register button (or triggers the event), the App client calls the registration and binding method as shown below:
Example code:
[[BCQQBindOrRegistManager sharedInstance] qqRegistWithMobile:mobile andWithVerifyCode:verifyCode andWithStateToken:_state_token andWithCompletionHandler:^(NSString * _Nonnull code, id _Nonnull data) {
}];Main methods of BCQQBindOrRegistManager:
/**
* Method name: sharedInstance
* @param none
* @return singleton instance
*/
+ (instancetype )sharedInstance ;
/**
* Method name: qqRegistWithMobile
* @brief: Auto-registration method after QQ login
* @param mobile mobile number
*@param StateToken `state_token` field obtained from the QQ login method
*@param verifyCode SMS verification code
* @param BCQQRegistCompleteHandler callback
**/
-(void)qqRegistWithMobile:(NSString*)mobile andWithVerifyCode:(NSString*)verifyCode andWithStateToken: (NSString*)StateToken andWithCompletionHandler:(BCQQRegistCompleteHandler)completeHandler;BCQQBindOrRegistManager callback codes:
| Code | Description |
|---|---|
| code=0 | Login succeeded. data= { "session_token": "btsiBjx85prcZu6I6Ki057Tmw3nSF2VO", "id_token": value, "expire": 432000,//NSNumber "status": "SUCCESS" } |
| code=1 | Login failed. data returns a string describing the error. |
| code=error code (refer to BambooCloud IDaaS return codes) | Login unsuccessful. data returns an error description. |
IDToken Verification and User Info Retrieval
After a successful login, session_token and id_token are returned. id_token can be used to obtain user information and verify login validity.
Flow:
- Verify
idToken. - Get user information from
id_token(you can call this method without verifying first).
Verify id_token
Example call:
[[BCIDAIDTokenManager sharedInstance] verifySignWithIdToken:idToken andWithCallBack:^(NSString * _Nonnull code, id _Nonnull data) {
}];BCIDAIDTokenManager overview:
/**
* Method name: sharedInstance
* @param none
* @return singleton instance
*/
+ (instancetype )sharedInstance;
/**
* Method name: verifySignWithIdToken
* @brief: Verify whether id_token is within the login validity period and matches the application
* @param idToken returned at login
* @param BCIDAIdTokenVerifyHandlerBlock callback:
NSString code
id data
**/
-(void)verifySignWithIdToken:(NSString*)idToken andWithCallBack:(BCIDAIdTokenVerifyHandlerBlock)callback;Return values:
| code(NSString) | data | Data Type and Description |
|---|---|---|
| 0 | success | [NSString] Signature verification succeeded |
| 1 | Error description | [NSString] Input parameter is empty, or SDK initialization parameters domain and clientID are not set |
| 106 | Expired | [NSString] Expired id_token |
| 107 | clientID mismatch | [NSString] Possibly used a clientID from another application |
| 103 | Signature verification failed | [NSString] Signature verification process failed |
| 102 | Public key empty | [NSString] Error during signature verification |
| See error code list at the end | See error code list at the end | Other error codes at the end of this document may also be returned |
Parse User Info from idToken
Example call:
[[BCIDAIDTokenManager sharedInstance] getUserInfoFromIdTokenWithIdToken:idToken andWithCallBack:^(NSString * _Nonnull code, id _Nonnull data) {
}];BCIDAIDTokenManager overview:
/**
* Method name: sharedInstance
* @param none
* @return singleton instance
*/
+ (instancetype )sharedInstance;
/**
* Method name: getUserInfoFromIdTokenWithIdToken
* @brief: Parse user information from id_token
* @param idToken returned at login
* @param BCIDAIdTokenGetInfoHandlerBlock callback:
NSString code
id data
**/
-(void)getUserInfoFromIdTokenWithIdToken:(NSString*)idToken andWithCallBack:(BCIDAIdTokenGetInfoHandlerBlock)callback;User information parameters:
| Parameter | Description |
|---|---|
| iss | Token issuer |
| aud | Token recipient, the application's clientId |
| exp | Token expiration time |
| jti | Token ID |
| iat | Token issuance time |
| sub | Fixed as subject |
| name | User name |
| mobile | User mobile number |
| id | User ID |
| userName | Username |
| User email |
Callback return value:
Success example:
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"
}Refresh IDToken
Example call:
[[BCIDAIDTokenRefreshManager sharedInstance] refreshIdTokenWithSessionToken:sessionToken andWithCallBack:^(NSString * _Nonnull code, id _Nonnull data) {
NSString* jsonS=(NSString*)data;
NSDictionary* dict= [self dictionaryWithJsonString:jsonS];//Parse jsonStr to NSDictionary
NSString* idTok= [dict objectForKey:@"id_token"];
NSString* session_tok=[dict objectForKey:@"session_token"];
NSString* expr=[dict objectForKey:@"expire"];
}];BCIDAIDTokenManager overview:
/**
* Method name: sharedInstance
* @param none
* @return singleton instance
*/
+ (instancetype )sharedInstance;
/**
* Method name: refreshIdTokenWithSessionToken
* @brief: Refresh id_token
* @param sessionToken returned at login
* @param BCIDAIdTokenRefreshIDTokenHandlerBlock callback:
NSString code
id data
**/
-(void)refreshIdTokenWithSessionToken:(NSString*)sessionToken andWithCallBack:(BCIDAIdTokenRefreshIDTokenHandlerBlock)callBack;Callback return value:
Success example:
code=0
data=
{
"id_token" : "eyJraWQiOiJhODJkzJjLmlkYWFzLXRllKp6w",
"session_token" : "apcOKuyry7kASh9h6mtf2G2GbettkyiU",
"expire" : 7200
}
Failure example (no data obtained)
code=1Return Codes
| Status Code | Error Code | Error Message | Chinese Error Message | Remediation |
|---|---|---|---|---|
| 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} 接口出错 | |
| 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: | 无效的用户名或密码。 其余登录尝试次数: | |
| 400 | IDAAS.SDK.LOGIN.1006 | Configuration error, unable to find wechat authentication source | 配置错误,找不到QQ认证源 | |
| 400 | IDAAS.SDK.LOGIN.1007 | Configuration error, unable to find alipay authentication source | 配置错误,找不到QQ认证源 | |
| 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 | 访问控制身份验证源类型转换错误 |