Fatsecret APIを使用するために oauth_signature を生成しようとしていますが、無効な署名エラーが発生します - 理由がわかりません。署名値の生成について、ここで説明したすべての手順(手順 2 を参照) をできるだけ正確に実行しようとしました。彼らが言うには:
[RFC2104] で定義されている HMAC-SHA1 署名アルゴリズムを使用してリクエストに署名します。ここで、テキストは署名ベース文字列であり、キーは「&」文字で区切られたコンシューマー シークレットとアクセス シークレットの連結値です (「&」を表示)一部のメソッドはアクセストークンを必要としないため、Access Secret が空の場合でも)。
計算されたダイジェスト オクテット文字列は、最初に [RFC2045] に従って base64 でエンコードされ、次に [RFC3986] パーセント エンコード (%xx) メカニズムを使用してエスケープされます。これが oauth_signature です。
base64 エンコーディングには、QSStrings.hを使用しました。
私がコーディングした手順は次のとおりです。
- (void)viewDidLoad
{
NSTimeInterval intervalFloat = [[NSDate date] timeIntervalSince1970];
int interval = (int) intervalFloat;
NSLog(@"time interval: %d",interval);
//for oauth_nonce random string
NSString *randomString = [self genRandString]; //see definition below
NSLog(@"%@",randomString);
NSString *requestString = [NSString stringWithFormat:@"POST&http%3A%2F%2Fplatform.fatsecret.com%2Frest%2Fserver.api&format%3Djson%26method%3Dprofile.create%26oauth_consumer_key%3Db753c99ccxxxxxx%26oauth_nonce%3D%@%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D%d%26oauth_version%3D1.0",randomString,interval];
NSString *secret = @"3959096c04xxxxxxxx&";
NSString *encodedStr = [self hmacsha1:requestString secret:secret]; //see definition below
NSLog(@"encodedStr: %@",encodedStr);
NSString *encodedString = [self urlEncodeValue:encodedStr]; //see definition below
NSLog(@"encodedString: %@",encodedString);
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://platform.fatsecret.com/rest/server.api?format=json&method=profile.create&oauth_consumer_key=b753c99ccxxxxxx&oauth_nonce=%@&oauth_signature=%@&oauth_signature_method=HMAC-SHA1&oauth_timestamp=%d&oauth_version=1.0",randomString, encodedString,interval]];
_request = [ASIFormDataRequest requestWithURL:url];
[_request setPostValue:@"json" forKey:@"format"];
[_request setPostValue:@"profile.create" forKey:@"method"];
[_request setPostValue:@"b753c99ccxxxxxx" forKey:@"oauth_consumer_key"];
[_request setPostValue:randomString forKey:@"oauth_nonce"];
[_request setPostValue:encodedString forKey:@"oauth_signature"];
[_request setPostValue:@"HMAC-SHA1" forKey:@"oauth_signature_method"];
[_request setPostValue:[NSNumber numberWithInt:interval] forKey:@"oauth_timestamp"];
[_request setPostValue:@"1.0" forKey:@"oauth_version"];
[_request setDelegate:self];
_request.timeOutSeconds = 60.0;
[_request startAsynchronous];
}
上記のコードで使用したメソッドの定義は次のとおりです。
- (NSString *)hmacsha1:(NSString *)data secret:(NSString *)key {
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hash = [QSStrings encodeBase64WithData:HMAC];
NSLog(@"Hash: %@", hash);
return hash;
}
NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-(NSString *) genRandString {
//fixing length of 4 chars
NSMutableString *randomString = [NSMutableString stringWithCapacity: 4];
for (int i=0; i<4; i++) {
[randomString appendFormat: @"%C", [letters characterAtIndex: arc4random() % [letters length]]];
}
return randomString;
}
- (NSString *)urlEncodeValue:(NSString *)str
{
NSMutableString * output = [NSMutableString string];
const unsigned char * source = (const unsigned char *)[str UTF8String];
int sourceLen = strlen((const char *)source);
for (int i = 0; i < sourceLen; ++i) {
const unsigned char thisChar = source[i];
if (thisChar == ' '){
[output appendString:@"+"];
} else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
(thisChar >= 'a' && thisChar <= 'z') ||
(thisChar >= 'A' && thisChar <= 'Z') ||
(thisChar >= '0' && thisChar <= '9')) {
[output appendFormat:@"%c", thisChar];
} else {
[output appendFormat:@"%%%02X", thisChar];
}
}
return output;
}
ここから私のプロジェクトをダウンロードすることで問題を確認できます