2012-06-26 14 views
5

मैंने किसी दिए गए शर्त पर अपनी ट्विटर स्थिति अपडेट करने के लिए एक बहुत ही सरल एप्लिकेशन लिखा है। मैंने OAuth हस्ताक्षर बनाने की आवश्यकता को समझने के लिए ट्विटर दस्तावेज़ का उपयोग किया है और यह भी प्राधिकरण शीर्षलेख को कैसे व्यवस्थित किया जाए। मैं फिर PHP में curl के साथ अनुरोध भेजता हूं।मैं ओथ के साथ प्रमाणित क्यों नहीं कर सकता?

चहचहाना देव साइट पर OAuth उपकरण का उपयोग करना, मैं दोनों अपने हस्ताक्षर आधार स्ट्रिंग और प्राधिकरण हैडर तुलना में, और दोनों बिल्कुल एक जैसे हैं:

हस्ताक्षर बेस स्ट्रिंग

POST&https%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json&oauth_consumer_key%3DYNxxxxxxxxxxxWnfI6HA%26oauth_nonce%3D31077a3c7b7bee4e4c7e2b5185041c12%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1340729904%26oauth_token%3D2991771-4csoiO2fxmWgSxxxxxxxxxxDjWj2AbyxATtiuadNE%26oauth_version%3D1.0%26status%3Dblah%2520test%2520blah. 

प्राधिकरण हेडर

Authorization: OAuth oauth_consumer_key="YN4FLBxxxxxxxxxxI6HA", oauth_nonce="31077a3c7b7bee4e4c7e2b5185041c12", oauth_signature="M2cXepcxxxxxxxxxxAImeAjE%2FHc%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1340729904", oauth_token="2991771-4cxxxxxxxxxxSmRvjzMoooMDjWj2AbyxATtiuadNE", oauth_version="1.0" 

स्पष्ट रूप से मैंने इसे बदल दिया है मेरे डेटा को छिपाने के लिए x के साथ ओमे वर्ण, लेकिन चरित्र के लिए दो वर्णों की तुलना करने से बिल्कुल वही परिणाम मिलता है। संदर्भ के लिए, मैं टाइमस्टैम्प को हार्ड-कोड करता हूं और यह नहीं करता कि OAuth टूल उत्पन्न करता है ताकि मेरे मान जांचने के लिए समान हो सकें। मेरा एक्सेस स्तर पढ़ने और लिखने के लिए सेट है। उसी पृष्ठ पर एक अंतिम उदाहरण है - कमांड लाइन पर curl के साथ चलाने के लिए आदेश। जब मैं यह आदेश चलाता हूं, तो यह पूरी तरह से काम करता है और बिना किसी समस्या के मेरे ट्विटर फ़ीड पर पोस्ट करता है।

इस बात को ध्यान में रखते हुए मुझे विश्वास है कि अब तक जो कुछ भी मैंने बनाया है वह ठीक है, और ऐसा नहीं लगता कि मुझे पहले से बताए गए विवरण उत्पन्न करने वाले कोड को पोस्ट करने में बहुत कुछ है। हालांकि कोड है कि मैं कॉल करने के लिए, cURL का उपयोग कर का उपयोग करें, मुझे लगता है कि अपराधी है, लेकिन यह नहीं बता सकता क्यों:

<?php 
// ... 
$curl = curl_init(); 

curl_setopt($curl, CURLOPT_URL, $baseUrl); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($curl, CURLOPT_POST, true); 
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: $header")); 
curl_setopt($curl, CURLOPT_POSTFIELDS, array('status' => $status)); 
$result = json_decode(curl_exec($curl)); 
curl_close($curl); 

var_dump($result); 

ध्यान दें कि $baseUrl, $header और $status एक ही हस्ताक्षर पैदा करने में इस्तेमाल किया चर हैं आधार स्ट्रिंग और प्राधिकरण शीर्षलेख, जो ठीक से मेल खाता है।

पेज के उत्पादन में जब रन है:

object(stdClass)#1 (2) { ["error"]=> string(34) "Could not authenticate with OAuth." ["request"]=> string(23) "/1/statuses/update.json" } 

मुझे आशा है कि पर्याप्त विवरण किसी को सही दिशा में मुझे बात करने के लिए के लिए यहाँ देखते हैं!

+0

क्या आपने https://dev.twitter.com/discussions/305 (उदा। यूआरएल की जांच करें) और https://dev.twitter.com/discussions/308 (उदा। HTTPS विकल्प सत्यापित करें) देखा है? – Will

+0

दुर्भाग्य से, हाँ। जैसा कि मैंने कहा, हस्ताक्षर आधार स्ट्रिंग और प्राधिकरण शीर्षलेख बिल्कुल वही हैं, और कमांड लाइन कर्ल पूरी तरह से काम करता है, यह इनमें से कोई भी नहीं हो सकता है। – LeonardChallis

+0

एक ही समस्या थी। धन्यवाद! – bozdoz

उत्तर

2

भी बहुत कुछ खोज के बाद, apache_request_headers() के साथ परीक्षण और धारणा है कि मेरे डेटा ठीक है और यह cURL था, जहां समस्या रखी लिए चिपके हुए, मैंने महसूस किया कि cURL multipart/form-data; के रूप में अनुरोध के Content-type की स्थापना की गई थी और सीमा जानकारी जोड़ने, स्पष्ट रूप से अब Content-Length फ़ील्ड के साथ भी। इसका मतलब था कि स्थिति सही नहीं भेजी जा रही थी, मुझे लगता है कि एक विकृत multipart/form-data; अनुरोध के कारण।

समाधान इसे एक स्ट्रिंग के रूप में भेजने के लिए था।उदाहरण के लिए, इस काम करता है:

curl_setopt($curl, CURLOPT_POSTFIELDS, 'status='. rawurlencode($status)); 

लेकिन मैंने पाया एक और भी अच्छे तरह से बनाया जा सकता है (विशेष रूप से एक से अधिक मान, जब मैं एक सरणी का उपयोग करना चाहते के साथ):

$postfields = array('status' => $status); 
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postfields)); 

जो बहुत अच्छे IMHO लग रहा है।

1

मुझे लगता है कि यह आपका nonce है। docs से: "oauth_nonce पैरामीटर एक अद्वितीय टोकन है जो आपके आवेदन को प्रत्येक अद्वितीय अनुरोध" (जोर मेरा) के लिए उत्पन्न होना चाहिए।

चेतावनी: मैं OAuth 2 + PHP की बजाय ओएथ 2 + जावा या जावास्क्रिप्ट से अधिक परिचित हूं।

यदि यह नहीं है (या केवल एक चीज नहीं है), तो आप उस पृष्ठ पर दस्तावेज़ के नमूना अनुरोध पर अपने वास्तविक HTTP अनुरोध (उदाहरण के लिए वायरशर्क का उपयोग करके) की तुलना कर सकते हैं। "हेडर स्ट्रिंग का निर्माण" पर भी नोट मदद कर सकता है।

+0

गैर-उत्पन्न करने वाले व्यक्ति को अलग करने का कोई तरीका नहीं होगा। जैसा कि मैंने कहा, प्रमाणीकरण हेडर और बेस स्ट्रिंग * बिल्कुल वही * हैं, इसलिए कर्ल के माध्यम से चल रहे हैं, वे नहीं जानते होंगे/देखभाल करते हैं जिन्होंने पहले गैर-उत्पन्न किया था। नॉन मूल्यों की तुलना करने के लिए केवल कड़ी-कोडित थी। मुझे लगता है कि HTTP अनुरोध की तुलना करना तरीका है और वास्तव में मैंने अपने पेज पर '$ baseUrl' बदल दिया है और PHP curl कॉल बनाम curl कमांड लाइन के साथ परीक्षण किया है, लेकिन अभी तक कुछ भी स्पष्ट नहीं हुआ है। – LeonardChallis

+0

मुझे पूरा यकीन है कि ट्विटर पिछले नॉनों को कैश करेगा और दोहराने को अस्वीकार करेगा, इस प्रकार रीप्ले हमलों को रोक देगा। Http://oauth.net/core/1.0/#nonce देखें: "उपभोक्ता शॉल तब एक गैर-मान उत्पन्न करेगा जो उस टाइमस्टैम्प के साथ सभी अनुरोधों के लिए अद्वितीय है। एक गैर-यादृच्छिक स्ट्रिंग है, प्रत्येक अनुरोध के लिए विशिष्ट रूप से जेनरेट की गई है। सेवा प्रदाता को यह सत्यापित करने की अनुमति देता है कि एक अनुरोध पहले कभी नहीं किया गया है और गैर-सुरक्षित चैनल (जैसे HTTP) पर अनुरोध किए जाने पर रीप्ले हमलों को रोकने में मदद करता है। " – Will

+1

मुझे नहीं लगता कि आप मुझे समझ रहे हैं। एकमात्र बार जब मैं हार्डकोड को हार्डकोड करता हूं, तो मेरे प्राधिकरण शीर्षलेख और ट्विटर के जेनरेट किए गए लोगों के साथ हस्ताक्षर बेस स्ट्रिंग की तुलना करना है। मैंने जेनरेट किए गए कर्ल अनुरोध का परीक्षण किया जब वे यह सुनिश्चित करने के लिए मेल खाते थे कि यह पूरा हो जाएगा, और ऐसा हुआ। मैं फिर अपनी PHP स्क्रिप्ट में एक ही nonce का उपयोग करने की कोशिश नहीं करता। यह ** निश्चित रूप से nonce ** नहीं है। मेरी लिपि में मेरे पास एक ऐसा फ़ंक्शन है जो एक अद्वितीय नॉन उत्पन्न करता है। हालांकि आपके इनपुट के लिए धन्यवाद। – LeonardChallis