欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

IOS 腾讯AI智能闲聊接口鉴权

程序员文章站 2022-05-19 08:25:41
...

首先注册账号,添加自己的应用,获取APPID和APPKEY,这两个后面获取签名的时候要用到。

你好! 这是注册地址,很简单,此处略过。https://ai.qq.com/console/home

签名算法

  1. 计算步骤
    用于计算签名的参数在不同接口之间会有差异,但算法过程固定如下4个步骤。
    一、将<key, value>请求参数对按key进行字典升序排序,得到有序的参数对列表N
    二、将列表N中的参数对按URL键值对的格式拼接成字符串,得到字符串T(如:key1=value1&key2=value2),URL键值拼接过程value部分需要URL编码,URL编码算法用大写字母,例如%E8,而不是小写%e8
    三、将应用**以app_key为键名,组成URL键值拼接到字符串T末尾,得到字符串S(如:key1=value1&key2=value2&app_key=**)
    四、对字符串S进行MD5运算,将得到的MD5值所有字符转换成大写,得到接口请求签名
  2. 注意事项
    一、不同接口要求的参数对不一样,计算签名使用的参数对也不一样
    二、参数名区分大小写,参数值为空不参与签名
    三、URL键值拼接过程value部分需要URL编码
    四、签名有效期5分钟,需要请求接口时刻实时计算签名信息
    五、更多注意事项,请查看常见问题

上面是官网获取sign的流程,ios实现如下:

// An highlighted block
#import "AFNetWorking.h"
#import<CommonCrypto/CommonDigest.h>

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //
    
    NSString *app_id = @"你的应用APPID";
    NSString *APPKEY = @"你的应用APPKEY";
    NSString *time_stamp = [self getNowTime];
    NSString *nonce_str = [self randomStringWithLength:10];
    NSMutableDictionary *params = [[NSMutableDictionary alloc]initWithDictionary: @{
                                                                                    @"app_id":app_id,
                                                                                    @"time_stamp":time_stamp,
                                                                                    @"nonce_str":nonce_str,
                                                                                    @"session":@"10000",
                                                                                    @"question":@"你好?"
                                                                                    }];
    
    
    NSString *paramsAppend = [self sortedDictionary:params withAPPKEY:APPKEY];
    NSString *sign = [self md5:paramsAppend];
    params[@"sign"] = [sign uppercaseString];
    
    [self post:@"https://api.ai.qq.com/fcgi-bin/nlp/nlp_textchat" andData:params andCallback:^(id JSON) {
        NSLog(@"--%@", JSON);
    }];
}

#pragma mark --- 请求
- (void)post:(NSString *)url
     andData:(NSDictionary *)params
 andCallback:(void (^)(id JSON))callback{
    __block  AFHTTPSessionManager * manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    [manager.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain",nil];
    
    [manager POST:url parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (callback) {
            callback(responseObject);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if(error.code == -1009) {
            if (callback) {
                callback(nil);
            }
        } else if(error.code == -1001) {
            //网络超时
            if (callback) {
                callback(nil);
            }
            
        } else {
            if (callback) {
                callback(nil);
            }
            NSLog(@"Error: %@", error);
        }
    }];
}

#pragma mark --- 生成随机字符串
-(NSString *)randomStringWithLength:(NSInteger)len {
    NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    NSMutableString *randomString = [NSMutableString stringWithCapacity: len];
    
    for (NSInteger i = 0; i < len; i++) {
        [randomString appendFormat: @"%C", [letters characterAtIndex: arc4random_uniform([letters length])]];
    }
    
    return randomString;
}

#pragma mark --- 获取当前时间戳---10位
- (NSString *)getNowTime{
    NSDate* date = [NSDate dateWithTimeIntervalSinceNow:0];
    NSTimeInterval time=[date timeIntervalSince1970];
    NSString *timeSp = [NSString stringWithFormat:@"%.0f", time];
    
    return timeSp;
}

#pragma mark --- 字典的升序排列
- (NSString *)sortedDictionary:(NSDictionary *)dict withAPPKEY:(NSString *)APPKEY{
    //对数组进行排序
    NSArray *sortArray = [[dict allKeys] sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    
    //通过排列的key值获取value
    NSMutableArray *valueArray = [NSMutableArray array];
    for (NSString *sortsing in sortArray) {
        NSString *valueString = [dict objectForKey:sortsing];
        valueString = [valueString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        [valueArray addObject:valueString];
    }
    
    NSMutableArray *signArray = [NSMutableArray array];
    for (int i = 0; i < sortArray.count; i++) {
        NSString *keyValueStr = [NSString stringWithFormat:@"%@=%@",sortArray[i],valueArray[i]];
        [signArray addObject:keyValueStr];
    }
    
    NSString *appendKey = [NSString stringWithFormat:@"%@=%@",@"app_key",APPKEY];
    [signArray addObject:appendKey];
    
    NSString *sign = [signArray componentsJoinedByString:@"&"];
    
    return sign;
}

#pragma mark --- md5加密
- (NSString *)md5:(NSString *)input {
    const char *cStr = [input UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, strlen(cStr), digest );
    NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [output appendFormat:@"%02x", digest[i]];
    }
           
    return  output;
}

具体用到的方法有:
1.获取当前时间戳
2.字典的升序排列
3.md5加密
4.AFNetWorking请求

遇到的问题

Q:接口返回4096是为什么?

A:参考返回码可以发现4096是服务器发现请求参数不合法或者不存在。请开发者参考具体的接口请求参数约束条件进行自检。

若所有参数均符合要求,则请开发者检查API调用方式是否正常。

对于POST方式请求,检查HTTP请求头的Content-Type是否为application/x-www-form-urlencoded
对于POST方式请求,检查HTTP请求正文数据是否符合application/x-www-form-urlencoded协议要求(注意:请求正文不是一个JSON结构,而是URL键值对字符串)
Q:接口返回16388是为什么?

A:参考返回码可以发现16388是服务器检查请求签名时,发现签名不正确。请开发者参考接口鉴权的示例代码进行检查。

Q:接口返回16389是为什么?
这是没有授权的意思哦。你需要自己把调用的接口接入到你创建的应用哦。

github代码

https://github.com/xiaohuahao/tencent-jianquan.git