2012-11-04 44 views
7

मैं फैटसेक्रेट एपीआई का उपयोग करने के लिए oauth_signature का उत्पादन करने की कोशिश कर रहा हूं, लेकिन अमान्य हस्ताक्षर त्रुटि प्राप्त करना - क्यों नहीं पता लगा सकता है। मैंने हस्ताक्षर मूल्य पीढ़ी के लिए यथासंभव सटीक रूप से here (चरण 2 देखें) के सभी चरणों का पालन करने का प्रयास किया। वे कहते हैं कि:अमान्य हस्ताक्षर: oauth_signature

अनुरोध जहां पाठ हस्ताक्षर बेस स्ट्रिंग है और प्रमुख उपभोक्ता रहस्य और पहुँच गुप्त से अलग श्रेणीबद्ध मूल्यों है पर हस्ताक्षर करने के HMAC-SHA1 हस्ताक्षर एल्गोरिथ्म के रूप में द्वारा [RFC2104] परिभाषित का प्रयोग करें एक '&' चरित्र (& दिखाएं 'भले ही एक्सेस गुप्त खाली है, कुछ तरीकों के लिए एक्सेस टोकन की आवश्यकता नहीं है)।

गणना की पचाने ओकटेट स्ट्रिंग, पहले बेस 64 एन्कोडेड प्रति [RFC2045], तो [RFC3986] प्रतिशत एन्कोडिंग (% xx) प्रणाली का उपयोग कर भाग निकले oauth_signature है।

तरीकों मैं कोड में इस्तेमाल के लिए
- (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]; 

} 

परिभाषाएँ ऊपर इस प्रकार हैं::

बेस 64 एन्कोडिंग के लिए, मैं इस प्रकार के रूप में इस्तेमाल QSStrings.h

कदम मैं कोड किए जाते हैं

- (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 = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 

-(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; 
} 

आप मेरी परियोजना को here

से डाउनलोड करके समस्या देख सकते हैं

उत्तर

6

अटलास्ट मैंने स्वयं कोड में गलतियों को समझ लिया। लगभग 80% समस्या हल हो गई है। मैं इस जगह गलत कर रहा था:

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]; 

यहाँ मैं आधार स्ट्रिंग पहले से इनकोडिंग। चूंकि मैं कुछ प्रारूप के साथ स्ट्रिंग शुरू कर रहा हूं, यह http%3A%2F%2F को किसी प्रकार का अज्ञात प्रारूप के रूप में ले रहा था, इसे 0 के साथ बदल दिया गया था। इसलिए मैं पूरे कोड की जगह के रूप में:

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

//for timestamp 
NSTimeInterval intervalFloat = [[NSDate date] timeIntervalSince1970]; 
int interval = (int) intervalFloat; 
NSLog(@"time interval: %d",interval); 

//for oauth_nonce random string 
NSString *randomString = [self genRandString]; 
NSLog(@"%@",randomString); 

NSString *actualString = [NSString stringWithFormat:@"format=json&method=profile.create&oauth_consumer_key=b753c99ccd8****&oauth_nonce=%@&oauth_signature_method=HMAC-SHA1&oauth_timestamp=%d&oauth_version=1.0",randomString,interval]; 

NSString *firstEncode = [self urlEncodeValue:actualString]; 

NSLog(@"first encode: %@",firstEncode); 

NSMutableString *requestString = [[NSMutableString alloc] initWithString:@"GET&http%3A%2F%2Fplatform.fatsecret.com%2Frest%2Fserver.api&"]; 
[requestString appendString:firstEncode]; 
NSLog(@"base str: %@",requestString); 

NSString *secret = @"395********&"; 

NSString *encodedStr = [self hmacsha1:requestString secret:secret]; 
NSLog(@"encodedStr: %@",encodedStr); 

NSString *encodedString = [self urlEncodeValue:encodedStr]; 
NSLog(@"encodedString: %@",encodedString); 

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://platform.fatsecret.com/rest/server.api?format=json&method=profile.create&oauth_consumer_key=b753c99cc*******&oauth_nonce=%@&oauth_signature=%@&oauth_signature_method=HMAC-SHA1&oauth_timestamp=%d&oauth_version=1.0",randomString, encodedString,interval]]; 
NSLog(@"url: %@",url); 

_request = [ASIFormDataRequest requestWithURL:url]; 
[_request setPostValue:@"json" forKey:@"format"]; 
[_request setPostValue:@"profile.create" forKey:@"method"]; 
[_request setPostValue:@"b753c9*********" 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 setRequestMethod:@"GET"]; 
[_request addRequestHeader:@"Content-Type" value:@"application/json"]; 
[_request setDelegate:self]; 
_request.timeOutSeconds = 60.0; 
[_request startAsynchronous]; 

} 

मुझे आशा है कि यह किसी को मदद मिलती है।

+0

क्या यह 2 पैर वाली ओएथ प्रमाणीकरण है जिसे आप कोशिश कर रहे थे? मैं भी उसी बिंदु पर फंस गया हूं, इससे कोई फर्क नहीं पड़ता कि मैं हस्ताक्षर सही तरीके से उत्पन्न करने का प्रयास करता हूं, मैं एक "अवैध हस्ताक्षर" निकाय के साथ समाप्त होता हूं। मैंने तुम्हारा रास्ता भी कोशिश की, लेकिन मुझे यह नहीं मिला। उपरोक्त दृष्टिकोण में आप कितने सफल थे? –

+0

हां यह है। मैंने ब्राउज़र पर उपरोक्त कोड से मेरी जेनरेट की गई स्ट्रिंग का परीक्षण किया और यह ठीक काम कर रहा है। लेकिन मुझे नहीं पता कि सिम्युलेटर पर चलने से हस्ताक्षर त्रुटि क्यों मिलती है। क्या आपने डिवाइस पर यह कोशिश की है? – NightFury

+0

मैंने ब्राउज़र में जेनरेट की गई स्ट्रिंग की जांच की है! मैं केवल सिम्युलेटर में इसका परीक्षण कर रहा हूं क्योंकि मेरे डेवलपर खाते को अभी तक नवीनीकृत नहीं किया गया है। खैर, अगर यह ब्राउज़र में और डिवाइस में काम करता है तो मुझे लगता है कि यह ठीक होना चाहिए। मैं ब्राउज़र में जेनरेट किए गए यूआरएल की जांच करूंगा और काम से वापस आने पर आपको बता दूंगा। धन्यवाद। –