ฉันเห็นด้วยกับคุณ. คลาสการสนับสนุน OAuth แบบโอเพนซอร์สที่มีให้สำหรับแอป. NET นั้นยากที่จะเข้าใจซับซ้อนเกินไป (DotNetOpenAuth มีวิธีการเปิดใช้งานกี่วิธี) ออกแบบมาไม่ดี (ดูวิธีการที่มีพารามิเตอร์สตริง 10 ตัวในโมดูล OAuthBase.cs จาก Google นั้น ลิงค์ที่คุณให้มา - ไม่มีการจัดการของรัฐเลย) หรือไม่น่าพอใจ
ไม่จำเป็นต้องซับซ้อนขนาดนี้
ฉันไม่ใช่ผู้เชี่ยวชาญเรื่อง OAuth แต่ฉันได้สร้างคลาสผู้จัดการฝั่งไคลเอ็นต์ OAuth ซึ่งฉันใช้กับ Twitter และ TwitPic ได้สำเร็จ ใช้งานง่าย เป็นโอเพนซอร์สและมีให้ที่นี่: Oauth.cs
สำหรับการตรวจสอบใน OAuth 1.0a ... ตลกดีนะมีชื่อพิเศษและดูเหมือน "มาตรฐาน" แต่เท่าที่ฉันรู้บริการเดียวที่ใช้ "OAuth 1.0a" คือ Twitter ฉันเดาว่าเป็นมาตรฐานเพียงพอ โอเคอย่างไรก็ตามใน OAuth 1.0a วิธีการทำงานสำหรับแอปเดสก์ท็อปคือ:
คุณซึ่งเป็นผู้พัฒนาแอปลงทะเบียนแอปและรับ "รหัสผู้บริโภค" และ "ความลับของผู้บริโภค" ใน Arstechnica มีการวิเคราะห์ที่เขียนได้ดีว่าทำไมรุ่นนี้จะไม่ดีที่สุดแต่เป็นพวกเขากล่าวว่ามันเป็นสิ่งที่มันเป็น
แอปของคุณทำงาน ในครั้งแรกที่ทำงานผู้ใช้ต้องให้การอนุมัติอย่างชัดเจนเพื่อให้แอปส่งคำขอ REST ที่ตรวจสอบสิทธิ์โดยอัตโนมัติไปยัง Twitter และบริการในเครือเดียวกัน (เช่น TwitPic) ในการดำเนินการนี้คุณต้องผ่านขั้นตอนการอนุมัติซึ่งเกี่ยวข้องกับการอนุมัติอย่างชัดเจนโดยผู้ใช้ สิ่งนี้จะเกิดขึ้นในครั้งแรกที่แอปทำงานเท่านั้น แบบนี้:
- ขอ "โทเค็นคำขอ" Aka โทเค็นชั่วคราว
- เปิดหน้าเว็บโดยส่งโทเค็นคำขอนั้นเป็นพารามิเตอร์แบบสอบถาม หน้าเว็บนี้แสดง UI แก่ผู้ใช้โดยถามว่า "คุณต้องการให้สิทธิ์การเข้าถึงแอปนี้หรือไม่"
- ผู้ใช้ล็อกอินเข้าสู่หน้าเว็บ twitter และอนุญาตหรือปฏิเสธการเข้าถึง
- หน้า html ตอบกลับจะปรากฏขึ้น หากผู้ใช้ให้สิทธิ์การเข้าถึงจะมี PIN แสดงเป็นแบบอักษร 48 pt
- ตอนนี้ผู้ใช้จำเป็นต้องตัด / วางหมุดนั้นลงในกล่องฟอร์มของ windows แล้วคลิก "ถัดไป" หรือสิ่งที่คล้ายกัน
- จากนั้นแอปเดสก์ท็อปจะทำการร้องขอ "โทเค็นการเข้าถึง" ที่ผ่านการตรวจสอบสิทธิ์ คำขอ REST อื่น
- แอปเดสก์ท็อปจะได้รับ "โทเค็นการเข้าถึง" และ "ความลับการเข้าถึง"
หลังจากได้รับการอนุมัติแล้วแอปเดสก์ท็อปสามารถใช้ "โทเค็นการเข้าถึง" และ "ความลับการเข้าถึง" เฉพาะผู้ใช้ (พร้อมกับ "รหัสผู้ใช้" และ "ความลับของผู้บริโภค" เฉพาะแอป) เพื่อดำเนินการตามคำขอที่ได้รับการรับรองความถูกต้องในนามของผู้ใช้ ไปที่ Twitter สิ่งเหล่านี้จะไม่มีวันหมดอายุแม้ว่าผู้ใช้จะยกเลิกการอนุญาตแอปหรือหาก Twitter ยกเลิกการอนุญาตแอปของคุณด้วยเหตุผลบางประการหรือหากคุณสูญเสียโทเค็นการเข้าถึงและ / หรือความลับคุณจะต้องดำเนินการอนุมัติอีกครั้ง .
หากคุณไม่ฉลาดโฟลว์ UI สามารถจัดเรียงมิเรอร์โฟลว์ข้อความ OAuth แบบหลายขั้นตอนได้ มีวิธีที่ดีกว่า
ใช้การควบคุมเว็บเบราว์เซอร์และเปิดหน้าเว็บอนุญาตภายในแอปเดสก์ท็อป เมื่อผู้ใช้คลิก "อนุญาต" ให้ดึงข้อความตอบกลับจากการควบคุมเว็บเบราว์เซอร์นั้นแยก PIN โดยอัตโนมัติจากนั้นรับโทเค็นการเข้าถึง คุณส่งคำขอ HTTP 5 หรือ 6 รายการ แต่ผู้ใช้ต้องการเห็นไดอะล็อก Allow / Deny เพียงช่องเดียว เรียบง่าย
แบบนี้:
หากคุณได้รับการจัดเรียง UI ความท้าทายเดียวที่ยังคงอยู่คือการสร้างคำขอที่ลงนามโดยอัตโนมัติ การเดินทางนี้มีผู้คนจำนวนมากเนื่องจากข้อกำหนดในการลงนาม oauth เป็นประเภทเฉพาะ นั่นคือสิ่งที่คลาส OAuth Manager แบบง่ายทำ
ตัวอย่างรหัสเพื่อขอโทเค็น:
var oauth = new OAuth.Manager();
// the URL to obtain a temporary "request token"
var rtUrl = "https://api.twitter.com/oauth/request_token";
oauth["consumer_key"] = MY_APP_SPECIFIC_KEY;
oauth["consumer_secret"] = MY_APP_SPECIFIC_SECRET;
oauth.AcquireRequestToken(rtUrl, "POST");
นั่นแหล่ะ เรียบง่าย ดังที่คุณเห็นจากโค้ดวิธีการเข้าถึงพารามิเตอร์ oauth คือผ่านตัวทำดัชนีแบบสตริงเช่นพจนานุกรม เมธอด AcquireRequestToken จะส่งคำขอที่ลงนามโดย oauth ไปยัง URL ของบริการที่ให้โทเค็นคำขอหรือที่เรียกว่าโทเค็นชั่วคราว สำหรับ Twitter URL นี้คือ " https://api.twitter.com/oauth/request_token " ข้อกำหนด oauth ระบุว่าคุณต้องแพ็คชุดพารามิเตอร์ oauth (โทเค็น, token_secret, nonce, การประทับเวลา, รหัสผู้บริโภค, เวอร์ชันและการโทรกลับ) ในลักษณะใดวิธีหนึ่ง (เข้ารหัส URL และเข้าร่วมด้วยเครื่องหมายแอมเปอร์แซนด์) และในเชิงศัพท์ - เรียงลำดับสร้างลายเซ็นบนผลลัพธ์นั้นจากนั้นรวมพารามิเตอร์เดียวกันเหล่านั้นพร้อมกับลายเซ็นที่จัดเก็บไว้ในพารามิเตอร์ oauth_signature ใหม่ด้วยวิธีอื่น (รวมด้วยลูกน้ำ) คลาสตัวจัดการ OAuth จะดำเนินการให้คุณโดยอัตโนมัติ มันสร้าง nonces และการประทับเวลาและเวอร์ชันและลายเซ็นโดยอัตโนมัติ - แอปของคุณไม่จำเป็นต้องดูแลหรือตระหนักถึงสิ่งนั้น เพียงตั้งค่าพารามิเตอร์ oauth และทำการเรียกใช้เมธอดง่ายๆ ระดับผู้จัดการจะส่งคำขอและแยกวิเคราะห์การตอบกลับให้คุณ
ตกลงแล้วไง เมื่อคุณได้รับโทเค็นคำขอแล้วคุณจะเปิด UI ของเว็บเบราว์เซอร์ซึ่งผู้ใช้จะให้การอนุมัติอย่างชัดเจน ถ้าคุณทำถูกต้องคุณจะปรากฏในเบราว์เซอร์ในตัว สำหรับ Twitter URL สำหรับสิ่งนี้คือ " https://api.twitter.com/oauth/authorize?oauth_token= " พร้อมกับ oauth_token ต่อท้าย ทำในโค้ดดังนี้:
var url = SERVICE_SPECIFIC_AUTHORIZE_URL_STUB + oauth["token"];
webBrowser1.Url = new Uri(url);
(หากคุณทำสิ่งนี้ในเบราว์เซอร์ภายนอกที่คุณใช้System.Diagnostics.Process.Start(url)
)
การตั้งค่าคุณสมบัติ Url ทำให้ตัวควบคุมเว็บเบราว์เซอร์นำทางไปยังเพจนั้นโดยอัตโนมัติ
เมื่อผู้ใช้คลิกปุ่ม "อนุญาต" หน้าใหม่จะถูกโหลด เป็นรูปแบบ HTML และใช้งานได้เหมือนกับเบราว์เซอร์เต็มรูปแบบ ในรหัสของคุณลงทะเบียนตัวจัดการสำหรับเหตุการณ์ DocumentedCompleted ของตัวควบคุมเว็บเบราว์เซอร์และในตัวจัดการนั้นให้จับพิน:
var divMarker = "<div id=\"oauth_pin\">"; // the div for twitter's oauth pin
var index = webBrowser1.DocumentText.LastIndexOf(divMarker) + divMarker.Length;
var snip = web1.DocumentText.Substring(index);
var pin = RE.Regex.Replace(snip,"(?s)[^0-9]*([0-9]+).*", "$1").Trim();
นั่นคือการขูดหน้าจอ HTML เล็กน้อย
หลังจากจับพินแล้วคุณไม่จำเป็นต้องใช้เว็บเบราว์เซอร์อีกต่อไปดังนั้น:
webBrowser1.Visible = false; // all done with the web UI
... และคุณอาจต้องการเรียก Dispose () ด้วยเช่นกัน
ขั้นตอนต่อไปคือการรับโทเค็นการเข้าถึงโดยการส่งข้อความ HTTP อื่นพร้อมกับพินนั้น นี่คือการเรียก oauth ที่ลงนามอีกครั้งซึ่งสร้างขึ้นด้วยการสั่งซื้อและการจัดรูปแบบที่ฉันอธิบายไว้ข้างต้น แต่อีกครั้งมันง่ายมากกับคลาส OAuth.Manager:
oauth.AcquireAccessToken(URL_ACCESS_TOKEN,
"POST",
pin);
สำหรับ Twitter URL นั้นคือ " https://api.twitter.com/oauth/access_token "
ตอนนี้คุณมีโทเค็นการเข้าถึงแล้วและคุณสามารถใช้โทเค็นเหล่านี้ในคำขอ HTTP ที่ลงนามได้ แบบนี้:
var authzHeader = oauth.GenerateAuthzHeader(url, "POST");
... url
จุดสิ้นสุดของทรัพยากรอยู่ที่ไหน หากต้องการอัปเดตสถานะของผู้ใช้จะเป็น " http://api.twitter.com/1/statuses/update.xml?status=Hello "
จากนั้นตั้งค่าสตริงที่ลงในส่วนหัว HTTP ชื่อการอนุมัติ
ในการโต้ตอบกับบริการของบุคคลที่สามเช่น TwitPic คุณต้องสร้างส่วนหัว OAuth ที่แตกต่างกันเล็กน้อยดังนี้:
var authzHeader = oauth.GenerateCredsHeader(URL_VERIFY_CREDS,
"GET",
AUTHENTICATION_REALM);
สำหรับ Twitter ค่าของ URL และขอบเขตการยืนยันเครดิตคือ " https://api.twitter.com/1/account/verify_credentials.json " และ " http://api.twitter.com/ " ตามลำดับ
... และใส่สิ่งนั้นสตริงอนุมัติในส่วนหัว HTTP ที่เรียกว่าX-ตรวจสอบข้อมูลประจำตัว--Authorization จากนั้นส่งไปที่บริการของคุณเช่น TwitPic พร้อมกับคำขอใด ๆ ที่คุณส่ง
แค่นั้นแหละ.
โดยรวมแล้วรหัสสำหรับอัปเดตสถานะ Twitter อาจเป็นดังนี้:
// the URL to obtain a temporary "request token"
var rtUrl = "https://api.twitter.com/oauth/request_token";
var oauth = new OAuth.Manager();
// The consumer_{key,secret} are obtained via registration
oauth["consumer_key"] = "~~~CONSUMER_KEY~~~~";
oauth["consumer_secret"] = "~~~CONSUMER_SECRET~~~";
oauth.AcquireRequestToken(rtUrl, "POST");
var authzUrl = "https://api.twitter.com/oauth/authorize?oauth_token=" + oauth["token"];
// here, should use a WebBrowser control.
System.Diagnostics.Process.Start(authzUrl); // example only!
// instruct the user to type in the PIN from that browser window
var pin = "...";
var atUrl = "https://api.twitter.com/oauth/access_token";
oauth.AcquireAccessToken(atUrl, "POST", pin);
// now, update twitter status using that access token
var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
var request = (HttpWebRequest)WebRequest.Create(appUrl);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);
using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
MessageBox.Show("There's been a problem trying to tweet:" +
Environment.NewLine +
response.StatusDescription);
}
OAuth 1.0a มีความซับซ้อนภายใต้ฝาครอบ แต่ไม่จำเป็นต้องใช้ OAuth.Manager จะจัดการการสร้างคำขอ oauth ที่ส่งออกและการรับและการประมวลผลเนื้อหา oauth ในการตอบกลับ เมื่อคำขอ Request_token ให้ oauth_token แก่คุณแอปของคุณไม่จำเป็นต้องจัดเก็บ Oauth.Manager ฉลาดพอที่จะทำสิ่งนั้นโดยอัตโนมัติ ในทำนองเดียวกันเมื่อคำขอ access_token ได้รับโทเค็นการเข้าถึงและความลับกลับมาคุณไม่จำเป็นต้องจัดเก็บข้อมูลเหล่านั้นอย่างชัดเจน OAuth.Manager จะจัดการสถานะนั้นให้คุณ
ในการรันครั้งต่อ ๆ ไปเมื่อคุณมีโทเค็นการเข้าถึงและข้อมูลลับแล้วคุณสามารถสร้างอินสแตนซ์ OAuth.Manager ได้ดังนี้:
var oauth = new OAuth.Manager();
oauth["consumer_key"] = CONSUMER_KEY;
oauth["consumer_secret"] = CONSUMER_SECRET;
oauth["token"] = your_stored_access_token;
oauth["token_secret"] = your_stored_access_secret;
... แล้วสร้างส่วนหัวการอนุญาตตามด้านบน
// now, update twitter status using that access token
var appUrl = "http://api.twitter.com/1/statuses/update.xml?status=Hello";
var authzHeader = oauth.GenerateAuthzHeader(appUrl, "POST");
var request = (HttpWebRequest)WebRequest.Create(appUrl);
request.Method = "POST";
request.PreAuthenticate = true;
request.AllowWriteStreamBuffering = true;
request.Headers.Add("Authorization", authzHeader);
using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode != HttpStatusCode.OK)
MessageBox.Show("There's been a problem trying to tweet:" +
Environment.NewLine +
response.StatusDescription);
}
คุณสามารถดาวน์โหลดDLL ที่มีระดับ OAuth.Manager ที่นี่ นอกจากนี้ยังมี helpfile ในการดาวน์โหลดนั้น หรือคุณสามารถดู helpfile ออนไลน์
ดูตัวอย่างของแบบฟอร์ม Windows ที่ใช้ผู้จัดการนี้ที่นี่
ตัวอย่างการทำงาน
ดาวน์โหลดตัวอย่างการทำงานของเครื่องมือบรรทัดคำสั่งที่ใช้คลาสและเทคนิคที่อธิบายไว้ที่นี่: