สิงหาคม 2007
- ข้อมูลเบื้องต้น: เหตุใด AuthSub จึงสำคัญ
- การจัดการการตรวจสอบสิทธิ์
- AuthSub ที่ปลอดภัย (ลงทะเบียนแล้ว)
- รายการรหัสทั้งหมด
- สรุป
บทนำ: เหตุใด AuthSub จึงสำคัญ
ข้อดีของ Google Data APIs ("GData" แบบย่อ) คือการช่วยให้นักพัฒนาซอฟต์แวร์ สร้างแอปพลิเคชันที่โต้ตอบกับบริการของ Google ได้ กล่าวโดยละเอียดคือโทเค็นเหล่านี้ช่วยให้คุณเข้าถึงข้อมูลส่วนตัวของผู้ใช้เพื่อใช้ในแอปพลิเคชันได้ API ช่วยให้คุณ เขียนแอปพลิเคชันเพื่อซิงค์ นำเข้า ส่งออก และจัดการข้อมูลดังกล่าวได้ แม้ว่า API จะให้ความสามารถอันทรงพลังเหล่านี้แก่คุณ แต่คุณต้องอย่าลืมใช้ อย่างมีความรับผิดชอบ เนื่องจากข้อมูลผู้ใช้เป็นข้อมูลส่วนตัว คุณจึงต้องการเข้าถึงข้อมูลดังกล่าวอย่างปลอดภัย ส่วนสำคัญของกระบวนการนี้คือการตรวจสอบสิทธิ์ ไปยังเซิร์ฟเวอร์ของ Google อย่างปลอดภัย
สมมติว่าคุณมีเว็บแอปพลิเคชันใหม่ที่ยอดเยี่ยมซึ่งคุณต้องการเชื่อมโยงกับข้อมูลที่จัดเก็บไว้ในเว็บเซอร์วิสของ Google ตอนนี้คุณต้องตรวจสอบสิทธิ์เพื่อเข้าถึงข้อมูลส่วนตัวนี้ ทำไมไม่ใช้สิ่งที่ง่ายๆ อย่าง ClientLogin วิธีนี้ใช้ได้ แต่คุณจะต้องจัดการข้อมูลส่วนตัวมากขึ้น นั่นคือข้อมูลเข้าสู่ระบบของผู้ใช้ ClientLogin กำหนดให้แอปพลิเคชันของคุณต้องขอชื่อผู้ใช้และรหัสผ่าน Google ของผู้ใช้ ซึ่งเหมาะสำหรับแอปพลิเคชันเดสก์ท็อปที่ทำงานบนเครื่องส่วนตัวของผู้ใช้ แต่ไม่เหมาะสำหรับแอปพลิเคชันบนเว็บ นอกเหนือจากความรับผิดในการจัดการข้อมูลเข้าสู่ระบบเหล่านี้ในเซิร์ฟเวอร์ของคุณเองแล้ว ผู้ใช้บางรายที่ระมัดระวังมากกว่าอาจกังวลว่าคุณจะจัดเก็บข้อมูลของตน ข้อกังวลที่พบบ่อยอีกอย่างจากผู้ใช้คือหากต้องการให้สิทธิ์โปรแกรมเข้าถึงเฉพาะบริการใดบริการหนึ่ง (เช่น กิจกรรมใน Google ปฏิทิน) แต่ไม่ต้องการให้สิทธิ์เข้าถึงบริการอื่นๆ (เช่น เอกสารใน Google) AuthSub แก้ปัญหาทั้ง 2 อย่างนี้ได้โดยให้ผู้ใช้ตรวจสอบสิทธิ์ผ่านเซิร์ฟเวอร์ของ Google และอนุญาตให้โปรแกรมของคุณขอสิทธิ์เข้าถึงที่จำเป็นเท่านั้น
ตอนนี้คุณได้อ่านทฤษฎีเบื้องหลัง AuthSub มากพอแล้ว ก็ถึงเวลาไปเขียนโค้ดกัน สำหรับบทความนี้ ผมเลือกที่จะทำให้ทุกอย่างง่ายขึ้นและทำทุกอย่างภายในหน้า ASP เดียว แต่คุณควรจะสามารถผสานรวมเทคนิคที่แสดงที่นี่เข้ากับแอปพลิเคชันของคุณเองได้อย่างง่ายดาย
การจัดการการตรวจสอบสิทธิ์
แล้วคุณต้องทำอะไรบ้างจึงจะใช้ AuthSub ในเว็บแอปพลิเคชันได้จริงๆ ก่อนอื่น การนำเข้ามาตรฐานจากไลบรารีไคลเอ็นต์ GData มีดังนี้
<%@ Import Namespace="Google.GData.Client" %> <%@ Import Namespace="Google.GData.Extensions" %> <%@ Import Namespace="System.Net" %>
ตอนนี้สิ่งแรกที่คุณต้องทำคือส่งผู้ใช้ไปยัง URL ที่สร้างขึ้นมาเป็นพิเศษ ซึ่งจะช่วยให้เซิร์ฟเวอร์ของ Google จัดการการตรวจสอบสิทธิ์และเปลี่ยนเส้นทางผู้ใช้กลับไปยังเว็บไซต์ของคุณได้ โชคดีที่คุณไม่จำเป็นต้องสร้าง URL นี้ด้วยตนเอง เนื่องจากมีวิธีการสร้าง URL ให้คุณ ยกตัวอย่างเช่น:
authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
- target สตริงนี้มี URL ของเว็บแอปพลิเคชัน นี่คือตำแหน่งที่ระบบจะเปลี่ยนเส้นทางผู้ใช้ไปหลังจากตรวจสอบสิทธิ์
- ขอบเขต สตริงนี้จะกำหนดโดย API ที่คุณใช้ ซึ่งสอดคล้องกับฟีดรายการใดรายการหนึ่งใน GData API เช่น ฟีดที่มีข้อมูลปฏิทินทั้งหมดสำหรับผู้ใช้คือ "http://www.google.com/calendar/feeds/default/private/full"
- secure คือบูลีนที่แจ้งให้เซิร์ฟเวอร์ทราบว่าคุณลงทะเบียนกับ Google แล้วและจะลงนามในคำขอของคุณไปยังเซิร์ฟเวอร์ด้วยการเข้ารหัส โดยปกติแล้วอาร์กิวเมนต์นี้จะเป็นเท็จโดยค่าเริ่มต้น โดยเฉพาะอย่างยิ่งเมื่อทำงานในสภาพแวดล้อมการทดสอบ
- session นี่คือบูลีนอีกรายการที่ระบุว่าคุณต้องการ "โทเค็นเซสชัน" แทน "โทเค็นที่ใช้ครั้งเดียว" บทบาทของอาร์กิวเมนต์นี้จะชัดเจนยิ่งขึ้นในอีกสักครู่
หลังจากที่ผู้ใช้คลิก URL ที่สร้างขึ้น ระบบจะนำผู้ใช้ไปยังหน้าบัญชี Google ซึ่งอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้บัญชี Google ของตนเองได้ จากนั้นระบบจะเปลี่ยนเส้นทางผู้ใช้กลับไปยังหน้าเว็บที่คุณระบุในตัวแปร "target" แต่มีพารามิเตอร์การค้นหา "token" ซึ่งมีโทเค็นที่ใช้ได้ครั้งเดียว โดยปกติแล้ว โทเค็นนี้จะใช้ได้เพียงครั้งเดียวเท่านั้น กล่าวคือ ใช้เพื่อดำเนินการอย่างใดอย่างหนึ่งกับฟีดที่ระบุได้ อย่างไรก็ตาม หากคุณระบุพารามิเตอร์ "session" เป็น true คุณจะแลกเปลี่ยนพารามิเตอร์ดังกล่าวเป็น "โทเค็นเซสชัน" ที่ใช้ซ้ำได้จนกว่าผู้ใช้จะสิ้นสุดเซสชัน โดยทำได้ดังนี้
String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString();
ในส่วนนี้ คุณจะดึงโทเค็นจากพารามิเตอร์การค้นหาและแลกเปลี่ยนเป็น "โทเค็นเซสชัน" จากนั้นคุณสามารถเลือกจัดเก็บโทเค็นในอาร์เรย์ Session
ของ .NET โดยอัตโนมัติเพื่อบันทึกไว้ใช้ในภายหลัง หรือจะเลือกจัดเก็บโทเค็นไว้ในฐานข้อมูลก็ได้ ขั้นตอนถัดไปคือการใช้โทเค็นนี้เพื่อส่งคำขอที่ผ่านการตรวจสอบสิทธิ์
GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "My-Cool-Application"); authFactory.Token = (String) Session["token"]; CalendarService service = new CalendarService(authFactory.ApplicationName); service.RequestFactory = authFactory;
ในส่วนนี้ คุณตั้งค่าออบเจ็กต์ CalendarService เพื่อโต้ตอบกับ Google Calendar API โดยใช้ AuthSub ในการตรวจสอบสิทธิ์ โปรดทราบว่า "cl" ที่ใช้ในตัวสร้างสำหรับ GAuthSubRequestFactory
คือชื่อบริการของปฏิทิน คุณดูชื่อบริการอื่นๆ ได้ในคำถามที่พบบ่อยเกี่ยวกับ Google Data APIs
AuthSub ที่ปลอดภัย (ลงทะเบียนแล้ว)
หากเลือกลงทะเบียนเว็บแอปพลิเคชัน คุณจะเปิดใช้ความปลอดภัยอีกระดับขณะใช้ AuthSub ได้ ซึ่งจะช่วยให้คุณลงนามแบบดิจิทัลในคำขอทั้งหมดที่โค้ดของคุณสร้างขึ้นได้ เพื่อไม่ให้ผู้อื่นใช้โทเค็น AuthSub ที่ออกให้คุณได้ เว้นแต่จะมีคีย์ส่วนตัวของคุณ ขั้นตอนแรกคือการตรวจสอบว่าคุณสร้างลิงก์ AuthSub ที่ถูกต้องเมื่อเรียกใช้ AuthSubUtil.getRequestUrl
โดยตั้งค่าอาร์กิวเมนต์ "secure" เป็น true คุณจะต้องทำการเปลี่ยนแปลงโค้ดอื่นๆ อีก 2 รายการ ดังนี้
String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, rsaKey).ToString(); ... authFactory.PrivateKey = rsaKey;
ก่อนอื่น โปรดสังเกตว่าตอนนี้คุณส่งตัวแปร "rsaKey" ไปยังเมธอด exchangeForSessionToken
แทน null
นอกจากนี้ ยังใช้ตัวแปรเดียวกันนี้เพื่อตั้งค่าพร็อพเพอร์ตี้ของ GAuthSubRequestFactory
เมื่อตั้งค่าการเชื่อมต่อกับบริการด้วย ตัวแปร "rsaKey" คือ RSACryptoServiceProvider
ที่สอดคล้องกับคอมโพเนนต์คีย์ส่วนตัวของใบรับรอง x509 ที่คุณลงทะเบียนกับ Google
การสร้างคีย์ส่วนตัว RSA และใบรับรองแบบ Self-signed อาจทำให้สับสนเล็กน้อย โดยเฉพาะอย่างยิ่งเนื่องจาก .NET Framework ไม่เข้าใจคีย์หรือใบรับรองที่จัดเก็บในรูปแบบ PEM คำสั่งต่อไปนี้แสดงวิธีสร้างคีย์ส่วนตัวและใบรับรองสาธารณะโดยใช้ชุดเครื่องมือ OpenSSL
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \ '/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \ test_key.pem -out test_cert.pem openssl pkcs12 -export -in test_cert.pem -inkey test_key.pem \ -out test_cert.pfx -name "Testing Certificate"
ขั้นตอนแรกจะสร้างคีย์ส่วนตัวและใบรับรอง X509 สาธารณะทั้ง 2 รายการในรูปแบบ PEM ชื่อ "test_key.pem" และ "test_cert.pem" ตามลำดับ โปรดทราบว่าระบบตั้งค่าให้ลงทะเบียนใบรับรองกับ "www.example.com" ซึ่งอยู่ใน Mountain View, CA, US แทนที่ค่าที่เหมาะสมสำหรับบริษัทของคุณที่นี่ ไฟล์ "test_cert.pem" มีข้อมูลที่คุณต้องส่งในหน้าการลงทะเบียน AuthSub
ขั้นตอนที่ 2 จะสร้างไฟล์ PFX จากคีย์ส่วนตัวและใบรับรอง คุณสามารถนำเข้าไฟล์นี้ไปยังไลบรารีของไคลเอ็นต์ .NET เพื่อลงนามในคำขอที่ส่งไปยัง GData API แบบดิจิทัล โค้ดต่อไปนี้แสดงวิธีนําเข้าคีย์ส่วนตัวจากไฟล์ PFX ไปยังเว็บแอปพลิเคชัน
protected AsymmetricAlgorithm getRsaKey() { X509Certificate2 cert = new X509Certificate2("C:/MyAspSite/test_cert.pfx",""); RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider; return privateKey; }
ฟังก์ชัน getRsaKey()
ที่กำหนดโดยข้อมูลโค้ดนี้สามารถใช้แทนตัวแปร "rsaKey" ที่แสดงด้านบนเมื่อใช้เพื่อตรวจสอบสิทธิ์กับ API แน่นอนว่าควรแทนที่เส้นทางของไฟล์ด้วยตำแหน่งที่เหมาะสมของไฟล์ PFX ที่คุณสร้างขึ้น
รายการโค้ดที่สมบูรณ์
วิธีที่ง่ายที่สุดในการแสดงวิธีใช้วิธีการที่แสดงในส่วนก่อนหน้าคือการใช้ตัวอย่างจริง โค้ดตัวอย่างต่อไปนี้เป็นหน้า ASP อย่างง่ายที่ใช้ AuthSub เพื่อตรวจสอบสิทธิ์ผู้ใช้ จากนั้นจะพิมพ์กิจกรรมใน Google ปฏิทินของผู้ใช้
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <%@ Import Namespace="Google.GData.Client" %> <%@ Import Namespace="Google.GData.Extensions" %> <%@ Import Namespace="Google.GData.Calendar" %> <%@ Import Namespace="System.Net" %> <script runat="server"> void PrintCalendar() { GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "TesterApp"); authFactory.Token = (String) Session["token"]; CalendarService service = new CalendarService(authFactory.ApplicationName); service.RequestFactory = authFactory; EventQuery query = new EventQuery(); query.Uri = new Uri("http://www.google.com/calendar/feeds/default/private/full"); try { EventFeed calFeed = service.Query(query); foreach (Google.GData.Calendar.EventEntry entry in calFeed.Entries) { Response.Write("Event: " + entry.Title.Text + "<br/>"); } } catch (GDataRequestException gdre) { HttpWebResponse response = (HttpWebResponse)gdre.Response; //bad auth token, clear session and refresh the page if (response.StatusCode == HttpStatusCode.Unauthorized) { Session.Clear(); Response.Redirect(Request.Url.AbsolutePath, true); } else { Response.Write("Error processing request: " + gdre.ToString()); } } } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Test Site</title> </head> <body> <form id="form1" runat="server"> <h1>AuthSub Sample Page</h1> <div> <% GotoAuthSubLink.Visible = false; if (Session["token"] != null) { PrintCalendar(); } else if (Request.QueryString["token"] != null) { String token = Request.QueryString["token"]; Session["token"] = AuthSubUtil.exchangeForSessionToken(token, null).ToString(); Response.Redirect(Request.Url.AbsolutePath, true); } else //no auth data, print link { GotoAuthSubLink.Text = "Login to your Google Account"; GotoAuthSubLink.Visible = true; GotoAuthSubLink.NavigateUrl = AuthSubUtil.getRequestUrl(Request.Url.ToString(), "http://www.google.com/calendar/feeds/",false,true); } %> <asp:HyperLink ID="GotoAuthSubLink" runat="server"/> </div> </form> </body> </html>
บทสรุป
AuthSub ช่วยให้เว็บแอปพลิเคชันเข้าถึงข้อมูลที่จัดเก็บไว้ ในบัญชี Google ของผู้ใช้ได้อย่างปลอดภัยและมีการควบคุม การใช้ไลบรารีของไคลเอ็นต์ .NET จะช่วยให้คุณผสานรวมเว็บไซต์ที่ใช้ ASP กับบริการของ Google ได้อย่างง่ายดาย บทความนี้มีไว้เพื่อช่วยให้คุณเริ่มต้นใช้งานได้ แต่เราขอแนะนำให้คุณดูแหล่งข้อมูลเพิ่มเติมต่อไปนี้