SMS Login
Document Overview
This document describes how to integrate SMS login into an iOS client. With SMS login, a verification code is sent to the user's mobile number, and the user authenticates with the BambooCloud IDaaS server using the mobile number and SMS verification code.
In the SMS login scenario, the user enters a mobile number and taps the button to request an SMS verification code. A slider captcha is presented; after it passes, the BambooCloud IDaaS backend sends an SMS verification code to that number. The user enters the code and taps Login, the BambooCloud IDaaS backend authenticates the request, and returns tokens. The final authentication result is returned to the App.
Process Overview
Login Flow

Integration Flow
The user enters a mobile number, and the App client checks whether the number matches the format rules. The user taps Get Verification Code.
The App client calls the slider verification method. The BambooCloud IDaaS SDK requests the slider captcha initialization information from the BambooCloud IDaaS backend, and the slider captcha window is displayed.
The user drags the slider to complete the captcha. The BambooCloud IDaaS SDK collects the slider captcha information and requests verification from the BambooCloud IDaaS server.
The BambooCloud IDaaS server completes slider verification successfully and returns a token to the BambooCloud IDaaS SDK.
The BambooCloud IDaaS SDK uses the token to request that the BambooCloud IDaaS server send an SMS.
The user receives the SMS, enters the verification code, and taps Login.
The App client calls the BambooCloud IDaaS SDK SMS login method with the mobile number and verification code.
The BambooCloud IDaaS SDK requests SMS login. The BambooCloud IDaaS server initiates the authentication flow; on success it returns
session_tokenandid_tokento the BambooCloud IDaaS SDK, and on failure it returns an error code and message.The BambooCloud IDaaS SDK receives the login result and returns it to the App client, which then proceeds with its own flow.
The client can use
id_tokento verify login validity and obtain basic user information.The client can use
session_tokento refreshid_token.
Environment Setup
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.

Add Dependencies
No third-party SDK dependencies are required.
Add Main Libraries
AuthnCenter_common_2C.framework
AuthnCenter_SMSLogin_2C.bundle
AuthnCenter_SMSLogin_2C.frameworkDrag 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
The BambooCloud IDaaS SMS login SDK supports iOS 10 and later.
In Frameworks, Libraries, and Embedded Content, add the following libraries:

In Frameworks, Libraries, and Embedded Content, add the main libraries and dependencies, and add
-ObjCto Other Linker Flags.
In the menu bar, choose TARGETS > Info > Custom iOS Target Properties > App Transport Security Settings > Allow Arbitrary Loads, as shown below.

Configure bitcode. Set bitcode to NO, as shown below.

Development Integration
Import the header file:
Reference the following headers in AppDelegate:
#import <AuthnCenter_common_2C /BCIDACommonManager.h>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: call the initialization method in didFinishLaunchingWithOptions of AppDelegate.
//1. Basic configuration initialization
[[[[[BCIDACommonManager sharedInstance] initWithDomain:@"https://your-backend-tenant.com"] initWithClientID:@"your-tenant-clientID"] initWithSSLCerVerification:NO] setLogEnabled: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;Call Sequence
If international number support is enabled, call the international area code API first, bind and display it in the UI, and assemble the international area code (for example,
+86-13800000000) when passing mobile numbers to methods that require them. If international number support is not enabled, ignore this API.Call the slider verification and SMS sending method (
startSlidingVerifyCodePageWithMobileNumber), passing the mobile number.Call the SMS login method (
loginsBySMSWithMobile), passing the mobile number and SMS verification code.
Send SMS Verification Code
The App client needs its own UI containing the required components: mobile number input field, verification code input field, button or event to trigger sending the verification code, and Login button or event.
After the user enters the mobile number and before triggering the send-verification-code event, the App client checks the mobile number format.
When the send-verification-code event is triggered, the App client calls the BambooCloud IDaaS SDK method as shown below:
//Import the header
#import <AuthnCenter_SMSLogin_2C/BCSMSLoginSlideVerifyCodeManager.h>
//Triggered event
[BCSMSLoginSlideVerifyCodeManager startSlidingVerifyCodePageWithMobileNumber:mobileNumber andWithResultHandler:^(NSString * _Nonnull code, id _Nonnull data) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Slider verification result==%@==%@",code,data);
});
}];BCSMSLoginSlideVerifyCodeManager method overview:
/**
* Method name: startSlidingVerifyCodePageWithMobileNumber
* @brief: Launch the slider captcha. On success, an SMS is sent automatically. On slider failure, code=error code and data returns the reason. On SMS success, code=0.
*@ param mobile: mobile number with area code, e.g. "+86-13800000000", or without area code, e.g. "13800000000".
*@param complete: asynchronous result callback. code=0 means SMS sent successfully; other codes mean SMS sending failed or slider verification failed. Refer to BambooCloud IDaaS error codes and the returned data (string error description). code=105 and data="User closed" means the close button of the slider box was tapped.
**/
+(void)startSlidingVerifyCodePageWithMobileNumber:(NSString*)mobile andWithResultHandler:(BCSMSLoginSlideCodeHandlerBlock)resultHandler;Login with Mobile Number and SMS Verification Code
After the verification code is sent, the user receives the SMS, enters the code, and triggers the login event. The App client then invokes the SMS login flow as shown below:
[[BCLoginSMSManager sharedInstance] loginsBySMSWithMobile:mobileNumber andWithVerifyCode:verificationCode andWithCompletionHandler:^(NSString * _Nonnull code, id _Nonnull data) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
dispatch_async(dispatch_get_main_queue(), ^{
//Handle login success or failure
});
}];Main methods of BCLoginSMSManager:
/**
* Method name: loginsBySMSWithMobile
* @brief: SMS login method
* @param mobile mobile number
*@param verifyCode SMS verification code
* @param BCLoginSMSCompleteHandler () login result callback
**/
-(void) loginsBySMSWithMobile:(NSString*)mobile andWithVerifyCode:(NSString*)verifyCode andWithCompletionHandler:(BCLoginSMSCompleteHandler)completeHandler;BCLoginSMSCompleteHandler callback codes:
| Code | Description |
|---|---|
| code=0 | Login succeeded. data returns an NSDictionary: data=@{@"session_token":sessionTokenValue,@"id_token":idTokenValue}; |
| code=1 | Login failed. data returns a string describing the error. |
Get 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 and preferred area code.

The BambooCloud IDaaS SDK provides an API for obtaining international area codes:
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 methods 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 |
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.
- 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 | 配置错误,找不到微信认证源 | |
| 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 | 访问控制身份验证源类型转换错误 |