云之讯语音、短信验证码实现

使用云之讯语音验证码功能,需要到云之讯开放平台去注册对应的账号,才能使用。

这里http://www.ucpaas.com/doc/doc_rest3-2.jsp 是官方文档 ,需要自己研究第一行文字,才能

明白业务功能的实现点。

下面是一个封装好的类,针对使用该SDK的帮助类:

//
//  HYBUCSSDKHelper.h
//  UCSVoiceOrSMSVerifyCodeDemo
//
//  Created by 黄仪标 on 15/2/2.
//

#import <Foundation/Foundation.h>
#import "UCSEvent.h"
#import "UCSService.h"

/*!
 * 云之讯UCS SDK铺助类,封装对IM、智能验证、VOIP网络电话功能
 * @author huangyibiao
 */
@interface HYBUCSSDKHelper : NSObject<UCSEventDelegate>

/*!
 * 此处封装为单例
 */
+ (HYBUCSSDKHelper *)shared;

/*!
 *--------------------------------------------------------------------------
 * 下面的方法,是与云之讯平台连接相关的API
 *--------------------------------------------------------------------------*/

// 明文连接
- (NSInteger)connectWithClientNumber:(NSString *)clientNumber
                            password:(NSString *)clientPassword;

// 连接服务器(密文)
- (NSInteger)connect:(NSString *)token;

// 连接服务器(明文,指定IP,Port)
- (NSInteger)connect:(NSString *)hostAddress
                port:(NSString *)hostPort
        clientNumber:(NSString *)clientNumber
            password:(NSString *)clientPassword;

// 连接服务器(密文,指定IP,Port)
- (NSInteger)connect:(NSString *)hostAddress
            withPort:(NSString *)hostPort
           withToken:(NSString *)token;

// 获取与云之讯平台连接的状态
- (BOOL)isConnected;

/*!
 *--------------------------------------------------------------------------
 *         智能验证API
 *--------------------------------------------------------------------------*/
/**
 * 获取云验证码
 */
- (void)ucsVerifyCodeWithPhone:(NSString *)phone
                          seconds:(int)seconds;

/**
 * 验证码验证
 */
- (void)checkUcsVerifyCodeWithPhone:(NSString *)phone
                         verifycode:(NSString *)verifycode;

/*!
 *--------------------------------------------------------------------------
 *         语音验证码、短信验证码相关API
 *--------------------------------------------------------------------------*/
/**
 * 调起语音验证码接口
 */
- (void)voiceCodeTo:(NSString *)phone verifyCode:(NSString *)verifyCode;

/**
 * 调起短信验证码接口
 * @param phone 短信接收端手机号码集合,用英文逗号分开,每批发送的手机号数量不得超过100
 *              个(国内短信不要加前缀,国际短信号码前须带相应的国家区号,如日本:0081)
 * @param param 内容数据,用于替换模板中{数字},若有多个替换内容,用英文逗号隔开即可
 */
- (void)smsCodeTo:(NSString *)phone param:(NSString *)param;

@end

下面是实现文件,这里的网络库使用的是AFN:

#define kAccountSid @"" // 替换为您的sid
#define kAccountToken @""
#define kAppId @""
#define kAppName @""

#define kUCSBaseURL @"https://api.ucpaas.com"
#define kSoftVersion @"2014-06-30" // 云之讯REST API版本号。

@interface HYBUCSSDKHelper ()

@property (nonatomic, strong) UCSService *ucsService;
@property (nonatomic, copy)   NSString   *callerPhoneNumber; // 主叫号码
@property (nonatomic, copy)   NSString   *phoneNumber;       // 被叫号码

@end

@implementation HYBUCSSDKHelper

+ (HYBUCSSDKHelper *)shared {
  static HYBUCSSDKHelper *s_helper = nil;

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    if (s_helper == nil) {
      s_helper = [[[self class] alloc] init];
    }
  });

  return s_helper;
}

- (instancetype)init {
  if (self = [super init]) {
    self.ucsService = [[UCSService alloc] initWithDelegate:self];
  }
  return self;
}

/*!
 *--------------------------------------------------------------------------
 * 下面的方法,是与云之讯平台连接相关的API
 *--------------------------------------------------------------------------*/
// 明文连接
- (NSInteger)connectWithClientNumber:(NSString *)clientNumber password:(NSString *)clientPassword {
  return [self.ucsService connect:kAccountSid
                 withAccountToken:kAccountToken
                 withClientNumber:clientNumber
                    withClientPwd:clientPassword];
}

// 连接服务器(密文)
- (NSInteger)connect:(NSString *)token {
  return [self.ucsService connect:token];
}

// 连接服务器(明文,指定IP,Port)
- (NSInteger)connect:(NSString *)hostAddress
                port:(NSString *)hostPort
        clientNumber:(NSString *)clientNumber
            password:(NSString *)clientPassword {
  return [self.ucsService connect:hostAddress
                         withPort:hostPort
               withwithAccountSid:kAccountSid
                 withAccountToken:kAccountToken
                 withClientNumber:clientNumber
                    withClientPwd:clientPassword];
}

// 连接服务器(密文,指定IP,Port)
- (NSInteger)connect:(NSString *)hostAddress
            withPort:(NSString *)hostPort
           withToken:(NSString *)token {
  return [self.ucsService connect:hostAddress withPort:hostPort withToken:token];
}

// 查询帐号与服务器连接状态
- (BOOL)isConnected {
  return [self.ucsService isConnected];
}

/*!
 *--------------------------------------------------------------------------
 *         智能验证
 *--------------------------------------------------------------------------*/
/**
 * 获取云验证码
 */
- (void)ucsVerifyCodeWithPhone:(NSString *)phone
                       seconds:(int)seconds {
  [self.ucsService getVerificationCode:kAccountSid
                             withAppid:kAppId
                           withAppName:kAppName
                          withCodetype:1
                             withPhone:phone
                           withSeconds:seconds
                          withBusiness:1];
}

/**
 * 验证码验证
 */
- (void)checkUcsVerifyCodeWithPhone:(NSString *)phone
                         verifycode:(NSString *)verifycode {
  [self.ucsService doVerificationCode:kAccountSid
                            withAppid:kAppId
                            withPhone:phone
                       withVerifycode:verifycode];
}

/*!
 *--------------------------------------------------------------------------
 *         语音验证码、短信验证码相关API
 *--------------------------------------------------------------------------*/
/**
 * 调起语音验证码接口
 */
- (void)voiceCodeTo:(NSString *)phone verifyCode:(NSString *)verifyCode {
  AFHTTPRequestOperationManager *manager = [self operationManagerWithBaseUrl:kUCSBaseURL];

  // 获取系统当前的时间戳
  NSString *timestamp = [self timestamp];
  [manager.requestSerializer setValue:[self authorization:timestamp] forHTTPHeaderField:@"Authorization"];

  NSString *url = [NSString stringWithFormat:@"/%@/Accounts/%@/Calls/voiceCode?sig=%@",
                   kSoftVersion, kAccountSid, [self sig:timestamp]];
  NSDictionary *params = @{@"voiceCode" : @{@"appId"      : kAppId,
                                            @"to"         : phone,
                                            @"verifyCode" : verifyCode}};
  [manager POST:url parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"url: %@\nparmas: %@\nresponseObject:%@\nerrorMessage: %@ errorCode=%@ headers:%@",
                 operation.response.URL.absoluteString,
                 params,
                 responseObject,
                 responseObject[@"errorMessage"],
                 responseObject[@"errorCode"],
        operation.request.allHTTPHeaderFields);

    if ([responseObject isKindOfClass:[NSDictionary class]]) {
      NSLog(@"%@", responseObject);
    } else {

    }
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"error: %@", [error description]);
  }];
}

- (NSString *)timestamp {
  NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  [formatter setDateStyle:NSDateFormatterMediumStyle];
  [formatter setTimeStyle:NSDateFormatterShortStyle];
  [formatter setDateFormat:@"yyyyMMddHHmmss"];
  NSDate *datenow = [NSDate date];
  NSString *timestamp = [formatter stringFromDate:datenow];
  return timestamp;
}

- (NSString *)authorization:(NSString *)timestamp {
  // 使用Base64编码(账户Id + 冒号 + 时间戳)
  NSString *authorization = [NSString stringWithFormat:@"%@:%@", kAccountSid, timestamp];
  authorization = [self base64Encoding:authorization];
  return authorization;
}

- (NSString *)sig:(NSString *)timestamp {
  // URL后必须带有sig参数,sig= MD5(账户Id + 账户授权令牌 + 时间戳),共32位(注:转成大写)
  // 使用MD5加密(账户Id + 账户授权令牌 + 时间戳),共32位。
  NSString *sig = [NSString stringWithFormat:@"%@%@%@", kAccountSid, kAccountToken, timestamp];
  sig = [[self md5n:sig] uppercaseString];
  return sig;
}

/**
 * 调起短信验证码接口
 * @param phone 短信接收端手机号码集合,用英文逗号分开,每批发送的手机号数量不得超过100
 *              个(国内短信不要加前缀,国际短信号码前须带相应的国家区号,如日本:0081)
 * @param param 内容数据,用于替换模板中{数字},若有多个替换内容,用英文逗号隔开即可
 */
- (void)smsCodeTo:(NSString *)phone param:(NSString *)param {
  AFHTTPRequestOperationManager *manager = [self operationManagerWithBaseUrl:kUCSBaseURL];

  // 获取系统当前的时间戳
  NSString *timestamp = [self timestamp];
  [manager.requestSerializer setValue:[self authorization:timestamp] forHTTPHeaderField:@"Authorization"];

  NSString *url = [NSString stringWithFormat:@"/%@/Accounts/%@/Messages/templateSMS?sig=%@",
                   kSoftVersion, kAccountSid, [self sig:timestamp]];

  NSDictionary *params = @{@"templateSMS" : @{@"appId"      : kAppId,
                                              @"to"         : phone,
                                              @"templateId" : @(3177),
                                              @"param"      : param}};
  [manager POST:url parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"url: %@\nparmas: %@\nresponseObject:%@\nerrorMessage: %@ errorCode=%@ headers:%@",
          operation.response.URL.absoluteString,
          params,
          responseObject,
          responseObject[@"errorMessage"],
          responseObject[@"errorCode"],
          operation.request.allHTTPHeaderFields);

    if ([responseObject isKindOfClass:[NSDictionary class]]) {
      NSLog(@"%@", responseObject);
    } else {

    }
  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"error: %@", [error description]);
  }];
}

/*!
 * @brief 将字符串转换成二进制数据后,再进行base64编码
 * @return 返回base64编码后的字符串
 */
- (NSString *)base64Encoding:(NSString *)str {
  NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
  NSString *result = nil;
  // 判断是否是ios7及其以上版本
#define kIsIOS7OrLater ([UIDevice currentDevice].systemVersion.integerValue >= 7 ? YES : NO)
  if (kIsIOS7OrLater) {
    result = [data base64EncodedStringWithOptions:0];
  } else {
    result = [data base64Encoding];
  }
  return result;
}

#pragma mark - md5加密
/*!
 * @brief 将字符串本身进行md5加密,并将加密后的字符串返回
 * @return 返回加密后的字符串
 */
- (NSString *)md5n:(NSString *)str {
  const char *cStr = [str UTF8String];
  unsigned char result[16];
  CC_MD5(cStr, strlen(cStr), result);
  return [NSString stringWithFormat:
          @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
          result[0], result[1], result[2], result[3],
          result[4], result[5], result[6], result[7],
          result[8], result[9], result[10], result[11],
          result[12], result[13], result[14], result[15]];
}

#pragma mark - UCCEventDelegate
// 与云通讯平台连接成功
- (void)onConnectionSuccessful:(NSInteger)result {
  NSLog(@"与云通讯平台连接成功 result=%ld", result);
}

// 与云通讯平台连接失败或连接断开
- (void)onConnectionFailed:(NSInteger)reason {
  NSLog(@" 与云通讯平台连接失败或连接断开 reason=%ld", reason);
}

/*!
 *--------------------------------------------------------------------------
 *         智能验证:语音验证码、短信验证码相关API代理回调
 *--------------------------------------------------------------------------*/
// 云获取验证码成功  0:已经验证成功,1:已下发验证码到用户
- (void) onGetValiateCodeSuccessful:(NSInteger)nResult {
  NSLog(@"%@", nResult ? @"已下发验证码到用户" : @"已经验证成功");
}

// 云获取验证码失败
- (void) onGetValiateCodeFailed:(NSInteger)reason {
  NSLog(@"云获取验证码失败 reason=%ld", reason);
}

// 云验证成功
- (void) onDoValiateCodeSuccessful:(NSInteger)nResult {
  NSLog(@"云验证成功 result=%ld", nResult);
}

// 云验证失败
- (void) onDoValiateCodeFailed:(NSInteger)reason {
  NSLog(@"云验证失败 reason=%ld", reason);
}

- (AFHTTPRequestOperationManager *)operationManagerWithBaseUrl:(NSString *)url {
  // 开启菊花转
  [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;

  AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc]
                                            initWithBaseURL:[NSURL URLWithString:url]];
  manager.requestSerializer = [AFJSONRequestSerializer serializer];
  manager.responseSerializer = [AFJSONResponseSerializer serializer];
  manager.requestSerializer.stringEncoding = NSUTF8StringEncoding;
  [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
  [manager.requestSerializer setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
  [manager.requestSerializer setValue:@"256" forHTTPHeaderField:@"Content-Length"];
  manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json",
                                                                            @"text/html",
                                                                            @"text/json",
                                                                            @"text/javascript"]];
  return manager;
}

@end

上面部分源码是无用的,因为这是为后面追加功能而添加的,这里只说明语音、短信验证码功能的实现。

说明:这里提供的部分源码,不意味着是好的代码,具体还请参考官方文档说明。

时间: 2024-10-01 05:35:18

云之讯语音、短信验证码实现的相关文章

云通讯短信验证码接入测试全过程

问题描述 [IT桔子]成立一周年之际,一直有用户说社交属性有点弱.为了弥补,终于下决心抽些时间做个APP版本.于是有了下面的故事.对于APP来说.短信验证码引导新用户来注册可以说是必不可少了.[容联云通讯/容联易通]早就收录到了自家的平台.直接去注册,查找API,目测也就是几小时工作.不过事实上整个接入用了两天.吐槽如下:苦B码农,注册个帐号就不用说了.拿来帐号直接跳入[DEMO下载].桔子的后台主要逻辑都是用PHP实现,我自然是Down了一份[RESTServerDemoPHP版本].下载回来

别让小小的“短信验证码”毁了用户体验

短信是一种渐渐被遗忘的通信方式,但现在这种传统的数据通信业务逐渐改变了它原来所扮演的角色,成为了用户名口令基础之上的主流身份验证方式,在安全行业被称为双因素认证. 移动互联网的应用场景下,用户选择APP应用时在想些什么?用户如何放心进行移动支付?用户如何安全找回密码?而一众移动互联网公司又如何有效的通过短信注册码获取真实用户?当我们谈论"短信验证码"的时候,其实我们谈论的是:安全.快捷.稳定和用户体验. "短信验证码"靠什么崛起? 根据工信部数据显示,截至2015年

java-手机端的注册功能需要短信验证码 怎么用springmvc rest 还有httpclient实现

问题描述 手机端的注册功能需要短信验证码 怎么用springmvc rest 还有httpclient实现 开发工具eclipse 数据库mysql 框架spring springmvc mybatis 现在是不是都用http 一般的业务不用webservice cxf了 解决方案 需要用第三方短信接口,如容联云的 http://www.yuntongxun.com/activity/smsDemo#point2 解决方案二: 有阿里大鱼,便宜又靠谱,官网有sdk,用httplicent就可以调

spring-boot | 集成短信验证码服务

目前,手机号对于我们的日常生活有着非常重要的作用,特别是手机号码实名认证以后,手机号如同你的身份证一样记录着我们的各种信息.所以短信验证码作为手机号的验证方式也显得尤为重要.因此,很多公司或网站用短信验证码来验证我们的身份信息.常见的使用场景有:登录注册.信息修改.异常登录.找回密码等操作. 今天给大家分享一下如何接入当前应用比较广泛的阿里云短信服务平台和容联云短信平台,其实每个短信平台接入方式都大同小异. 首先我们需要去各家短信平台申请属于我们自己的开发者账号,容联云通讯会有一定数量的免费短信

IOS中快速集成短信SDK验证开发(SMSSDK),IOS开发中如何设置手机短信验证码_IOS

嘿嘿..sdk是别人的,我只是下载来集成一下. smssdk下载网站:http://www.mob.com/(也有其他很多网站有类似SDK,譬如https://www.juhe.cn/等等,可以自行百度,我在这里就演示一下MOB官网的) 此网站号称smssdk免费,可是进去一看........ 每天免费20条,上限登记了才永久免费.不多说了,开始...... 官网集成文档http://wiki.mob.com/ [1~3步]我就截图官方文档了,傻瓜式操作 [4.1]:先看官网说明: [4.2]再

Android中用Bmob实现短信验证码功能的方法详解_Android

 这篇文章主要介绍发送验证码和校验验证码的功能,用到一个第三方平台Bmob,那Bmob是什么呢?Bmob可以开发一个云存储的移动应用软件,他提供了大量的标准的API接口,根据需要接入相关服务,开发者可以更加专注于应用的开发,让产品交付更快速,验证码功能就是其中一个. 一.跟其他第三方一样,我们开发之前要做一些准备工作. 1.首先,去官网注册一个帐号:http://www.bmob.cn/: 2.然后就可以创建应用了:具体怎么做Bmob说得很清楚了(官方操作介绍),如果你不想看,我简单说一下:点击

php发送短信验证码完成注册功能_php实例

短信验证码注册,很简单,用的是  云通讯的短信系统(收费的,不过有测试的api给我们做测试).好了,不多说,进入正题.  1.收到到云通讯短信系统注册账号,然后下载他们的封装好的短信api接口代码,解压,然后找到CCPRestSDK.php文件和SendTemplateSMS.php文件,将其拉到根目录文件夹里. 2.打开SendTemplateSMS.php文件,首先注意include_once('./CCPRestSDK.php'),千万别包含错路径了,将云通讯给的测试主账号,主账号Toke

Android使用第三方服务器Bmob实现发送短信验证码_Android

调用Bmob第三方服务器实现短信验证的功能,大致思路如下: 随机产生6位数字,然后调用Bmob的请求短发函数发送者六位数到服务器,然后服务器给指定手机发送这6位验证码,然后感觉用户输入的数字进行判断,如果输入的和发送的相等,则验证成功. 第一步.请求验证码: SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String sendTime = format.format(new Date());

Spring MVC 中 短信验证码功能的实现方法_java

在外部网站中短信的验证很有必要,比如在实现注册.验证用户信息等的情况下.在SpringMVC中的实现如下: 短信接口 短信接口,有些企业会购买的有移动的短信平台接口.如果是个人或者是小企业可以使用一些云服务的.比如百度的API Store上面的. 我使用的是:http://apistore.baidu.com/apiworks/servicedetail/1018.html 当然短信接口肯定都是要付费的,而且是基于模板的,具体的使用说明可以看这个网址里面的使用说明. 前端界面 前端的界面,可能如