背景交代:
因为请求需要签名,签名要拼上请求参数的json字符串。发现一个问题,ios把参数转成json后会有一些类似空格和\n这样的格式符。导致算出来的签名是带上这些格式符的。服务端从请求体拿到的是个字典对象key=value,是没有这些格式符的。所有会签名校验失败。
因为这是ios字典转json产生的格式符,只能ios自己处理。
以下为过滤格式符的代码,暂时解决了有格式符产生算出签名不一致的问题。
NSString *messageJSON = @"";
if (![NSJSONSerialization isValidJSONObject:encodePram]) {
NSLog(@"不是有效的json类型");
return @"";
}else
{
messageJSON = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:encodePram options:NSJSONWritingPrettyPrinted error:NULL] encoding:NSUTF8StringEncoding];
}
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r\n" withString:@"" ];
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString : @"" ];
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\t" withString : @"" ];
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@" " withString : @"" ];
但是又引入一个问题,就是如果key或者value有空格和\n这类的格式符,那么真正有意义的内容就会被无意修改到,也会导致签名不对。
后来我想到的解决办法是,在转json前先把key和value进行urlencode,这时候出来的字符串就是带了json格式多余的那些空格和\n的,而内容key和value已经被urlencode,这时候过滤json格式符不会把真正的内容过滤掉。
过滤完之后,再对整个字符串来个urlDecode,问题解决。
+ (NSString *)yxNetWorkJsonString:(id)pram{
if (!([pram isKindOfClass:[NSDictionary class]]||[pram isKindOfClass:[NSArray class]])) {
return @"{}";
}
if (!pram) {
return @"{}";
}
//pram对key和value进行urlencode
id encodePram = [self urlEncodeKeyAndValue:pram];
NSString *messageJSON = @"";
if (![NSJSONSerialization isValidJSONObject:encodePram]) {
NSLog(@"不是有效的json类型");
return @"";
}else
{
messageJSON = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:encodePram options:NSJSONWritingPrettyPrinted error:NULL] encoding:NSUTF8StringEncoding];
}
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r\n" withString:@"" ];
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString : @"" ];
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\t" withString : @"" ];
messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@" " withString : @"" ];
//对整个字符串url decode
messageJSON = [messageJSON jk_urlDecode];
return messageJSON;
}
递归encode
+ (id)urlEncodeKeyAndValue:(id)target
{
if (!([target isKindOfClass:[NSDictionary class]]||[target isKindOfClass:[NSArray class]])) {
return nil;
}
if ([target isKindOfClass:[NSDictionary class]]) {
NSMutableDictionary *result = [NSMutableDictionary new];
[target enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
id NewKey = key;
id NewValue = obj;
if ([key isKindOfClass:[NSString class]]) {
NewKey = [key jk_urlEncode];
}
if ([obj isKindOfClass:[NSString class]]) {
NewValue = [obj jk_urlEncode];
}else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSArray class]])
{
NewValue = [self urlEncodeKeyAndValue:obj];
}
[result setObject:NewValue forKey:NewKey];
}];
return result;
}else
{
//array
NSMutableArray * result = [NSMutableArray new];
[target enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
id NewValue = obj;
if ([obj isKindOfClass:[NSString class]]) {
NewValue = [obj jk_urlEncode];
}else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSArray class]])
{
NewValue = [self urlEncodeKeyAndValue:obj];
}
[result addObject:NewValue];
}];
return result;
}
}
网友评论