OAuth ในไลบรารีของไคลเอ็นต์ Google Data Protocol

คำเตือน: หน้านี้เป็นข้อมูลเกี่ยวกับ API เก่าของ Google ซึ่งก็คือ Google Data API โดยเกี่ยวข้องกับ API ที่แสดงอยู่ในไดเรกทอรี Google Data API เท่านั้น ซึ่ง API หลายรายการถูกแทนที่ด้วย API ใหม่กว่าแล้ว ดูข้อมูลเกี่ยวกับ API ใหม่ที่เฉพาะเจาะจงได้ในเอกสารประกอบของ API ใหม่ ดูข้อมูลเกี่ยวกับการให้สิทธิ์คำขอด้วย API เวอร์ชันใหม่กว่าได้ที่การตรวจสอบสิทธิ์และการให้สิทธิ์บัญชี Google

เอกสารนี้อธิบายวิธีใช้ไลบรารีของไคลเอ็นต์ Google Data API เพื่อเชื่อมต่อกับการตรวจสอบสิทธิ์ OAuth สำหรับเว็บแอปพลิเคชันของ Google

อินเทอร์เฟซ OAuth ช่วยให้แอปพลิเคชันบนเว็บเข้าถึงบริการของ Google ในนามของผู้ใช้ได้ OAuth ช่วยให้แอปพลิเคชันได้รับโทเค็นการเข้าถึงโดยไม่ต้องจัดการข้อมูลการเข้าสู่ระบบบัญชีของผู้ใช้ เพื่อรักษาความปลอดภัยในระดับสูง

ไลบรารีของไคลเอ็นต์ Google Data API มีเมธอดที่จะช่วยให้คุณใช้ OAuth ในเว็บแอปพลิเคชันได้ โดยเฉพาะอย่างยิ่ง มีวิธีการสร้าง การขอโทเค็นคำขอ การให้สิทธิ์โทเค็นคำขอ และการแลกเปลี่ยนโทเค็นคำขอที่ได้รับอนุญาตเป็นโทเค็นเพื่อการเข้าถึง นอกจากนี้ ไลบรารียังจัดการ อัลกอริทึมการลงนามที่จำเป็นเมื่อส่งคำขอไปยังบริการข้อมูลของ Google

กลุ่มเป้าหมาย

เอกสารนี้มีไว้สำหรับโปรแกรมเมอร์ที่ต้องการให้แอปพลิเคชันบนเว็บเข้าถึงบริการของ Google ในนามของผู้ใช้ โดยใช้ไลบรารีของไคลเอ็นต์ Google Data APIs

เอกสารนี้ถือว่าคุณคุ้นเคยกับอินเทอร์เฟซ OAuth และกระบวนการทั่วไปในการรวม OAuth เข้ากับเว็บแอปพลิเคชัน ดูคำอธิบายโปรโตคอลของ OAuth ทั้งหมดได้ที่การตรวจสอบสิทธิ์ OAuth สำหรับเว็บแอปพลิเคชันหรือข้อกำหนดอย่างเป็นทางการที่ oauth.net

การใช้ OAuth แบบ 3 ทางและ Google Data APIs โดยไม่มีไลบรารีของไคลเอ็นต์

หากต้องการให้เว็บแอปพลิเคชันโต้ตอบกับบริการข้อมูลของ Google โดยใช้ OAuth เป็นวิธีการให้สิทธิ์ คุณสามารถดูข้อมูลทั้งหมดที่จำเป็นได้ในการตรวจสอบสิทธิ์ OAuth สำหรับเว็บแอปพลิเคชัน คุณไม่จำเป็นต้องใช้ไลบรารีของไคลเอ็นต์ Google Data APIs หากไม่ต้องการ

ต่อไปนี้คือโครงร่างของวิธีที่แอปพลิเคชันอาจตรวจสอบสิทธิ์ผู้ใช้โดยใช้ OAuth

  1. แอปพลิเคชันของคุณจะส่งคำขอที่ลงชื่อเพื่อดึงโทเค็นคำขอ OAuth เริ่มต้นจากปลายทาง OAuthRequestToken
  2. แอปพลิเคชันเปลี่ยนเส้นทางผู้ใช้ไปยัง URL ของ OAuthAuthorizeToken ที่เหมาะสมเพื่อให้สิทธิ์โทเค็นคำขอ
  3. เมื่อให้สิทธิ์เข้าถึงแล้ว ระบบจะเปลี่ยนเส้นทางผู้ใช้กลับไปยังแอปพลิเคชันของคุณ (URL oauth_callback)
  4. แอปพลิเคชันของคุณจะส่งคำขอที่ลงชื่อแล้วเพื่ออัปเกรดโทเค็นคำขอที่ได้รับอนุญาตเป็นโทเค็นเพื่อการเข้าถึงโดยใช้ปลายทาง OAuthGetAccessToken

ไลบรารีของไคลเอ็นต์ Google Data APIs ช่วยลดความซับซ้อนของกระบวนการให้สิทธิ์นี้ด้วยการจัดการรายละเอียดต่างๆ ให้คุณ เอกสารนี้จะอธิบายวิธีการ

การลงทะเบียนเว็บแอปพลิเคชัน

OAuth กำหนดให้การเรียก API ทั้งหมดต้องลงนามแบบดิจิทัล Google รองรับวิธีการลงนาม HMAC-SHA1 และ RSA-SHA1 หากต้องการลงนามในคำขอ แอปพลิเคชันของคุณต้องลงทะเบียนกับ Google ก่อน เมื่อลงทะเบียนแล้ว Google จะให้ คีย์ผู้บริโภค (และข้อมูลลับสำหรับใช้กับ HMAC-SHA1) รวมถึงที่สำหรับอัปโหลดใบรับรองสาธารณะแก่คุณ

1. การจดทะเบียนโดเมน

โปรดทำตามขั้นตอนที่ระบุไว้ในการลงทะเบียนสำหรับแอปพลิเคชันบนเว็บ

2. การสร้างคู่คีย์ส่วนตัว / ใบรับรองสาธารณะ (ไม่บังคับ)

หากเลือกใช้ RSA-SHA1 เป็น oauth_signature_method คุณจะต้องสร้างRSA คู่คีย์ส่วนตัวและใบรับรองสาธารณะแบบ Self-signing ดูตัวอย่างวิธีดำเนินการได้ที่การสร้างคีย์ส่วนตัวและใบรับรองสาธารณะที่ลงนามด้วยตนเอง (ด้านล่าง)

การทำงานกับ OAuth แบบ 3 ทางและ Google Data API: ตัวอย่างไลบรารีของไคลเอ็นต์

ส่วนต่อไปนี้แสดงตัวอย่างการใช้เมธอดไลบรารีของไคลเอ็นต์ Google Data APIs เพื่อทำตามขั้นตอนที่ระบุไว้ในส่วน "การทำงานกับ OAuth" ของเอกสารประกอบ OAuth ตัวอย่างทั้งหมดในเอกสารนี้ถือว่าโดเมนโฮสต์ของแอปพลิเคชันคือ example.com

การกําหนดขอบเขตของการเข้าถึงข้อมูล

บริการของ Google แต่ละรายการจะกำหนดค่า scope ที่กำหนดสิทธิ์เข้าถึงข้อมูลของผู้ใช้ของโทเค็น ค่าขอบเขตที่ใช้ได้จะแสดงอยู่ในคำถามที่พบบ่อยเกี่ยวกับข้อมูลของ Google ตัวอย่างเช่น หากต้องการใช้ API รายการเอกสาร ให้ตั้งค่า scope เป็น https://docs.google.com/feeds/ ตามที่ระบุไว้ในคำถามที่พบบ่อย

หมายเหตุ: ตั้งค่า scope เป็น URL ที่แคบที่สุดซึ่งอนุญาตให้เข้าถึงตามที่คุณต้องการ ซึ่งจะช่วยลดโอกาสในการรับและรั่วไหลของข้อมูลส่วนบุคคลโดยไม่ตั้งใจ เช่น หากต้องการเข้าถึงฟีดรายการเอกสารส่วนตัวของผู้ใช้ปัจจุบัน ให้ใช้ขอบเขต https://docs.google.com/feeds/default/private/full แทนขอบเขตที่กว้างกว่า เช่น https://docs.google.com/feeds/ ซึ่งให้สิทธิ์เข้าถึงฟีดรายการเอกสารทั้งหมด

โทเค็นแบบหลายขอบเขต

หากต้องการสร้างโทเค็นที่เข้าถึง Google Data API หลายรายการ ให้คั่นแต่ละขอบเขตด้วยอักขระช่องว่าง ตัวอย่างด้านล่างสร้างโทเค็นที่มีสิทธิ์เข้าถึงทั้งข้อมูลเอกสารใน Google และข้อมูล Google ปฏิทินของผู้ใช้

scope=https://www.google.com/calendar/feeds/ https://docs.google.com/feeds/
การเข้ารหัส URL

อักขระที่ไม่ใช่ ASCII ที่ปรากฏใน URL รวมถึงเครื่องหมายโคลอน เครื่องหมายทับ และช่องว่าง ต้องเข้ารหัส URL เพื่อให้ส่งผ่าน HTTP ได้ ไลบรารีของไคลเอ็นต์ Google Data API จะเข้ารหัส URL ของพารามิเตอร์ให้โดยอัตโนมัติ คุณจึงใช้สตริงที่ไม่ได้เข้ารหัส URL ได้เมื่อกำหนดค่าให้กับพารามิเตอร์ เช่น คุณกำหนดค่าต่อไปนี้ในโค้ดได้

scope=https://www.google.com/calendar/feeds/ https://docs.google.com/feeds/

เมื่อเรียกใช้ไลบรารีไคลเอ็นต์ ระบบจะเข้ารหัส URL พารามิเตอร์ scope เป็นค่าต่อไปนี้โดยอัตโนมัติ
https%3a%2f%2fwww.google.com%2fcalendar%2ffeeds%2f+https%3a%2f%2fdocs.google.com%2ffeeds%2f

การดึงโทเค็นคำขอ

Java

สำหรับ HMAC-SHA1 คุณต้องมีวิธีจัดเก็บรหัสลับของโทเค็น (ที่ได้รับในการตอบกลับ) เพื่อสร้างออบเจ็กต์โทเค็น OAuth ที่กลับมาจากหน้าการอนุมัติ โดยให้ตั้งค่าตัวแปรเซสชันหรือคุกกี้

import com.google.gdata.client.docs.*;
import com.google.gdata.client.authn.oauth.*;

String CONSUMER_KEY = "example.com";
String CONSUMER_SECRET = "abc123doremi";

GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET);
oauthParameters.setScope("https://docs.google.com/feeds/");
oauthParameters.setOAuthCallback("http://www.example.com/UpgradeToken.jsp");

GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer());
oauthHelper.getUnauthorizedRequestToken(oauthParameters);

เมื่อใช้ RSA-SHA1 ระบบจะไม่ใช้ oauth_token_secret จึงไม่จำเป็นต้องเก็บรหัสลับของโทเค็นไว้

import com.google.gdata.client.docs.*;
import com.google.gdata.client.authn.oauth.*;

String CONSUMER_KEY = "example.com";

GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
oauthParameters.setScope("https://docs.google.com/feeds/");
oauthParameters.setOAuthCallback("http://www.example.com/UpgradeToken.jsp");

PrivateKey privKey = getPrivateKey("/path/to/your/rsakey.pk8");

GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthRsaSha1Signer(privKey));
oauthHelper.getUnauthorizedRequestToken(oauthParameters);

...

public static PrivateKey getPrivateKey(String privKeyFileName) {
  File privKeyFile = new File(privKeyFileName);
  FileInputStream fis = new FileInputStream(privKeyFile);
  DataInputStream dis  = new DataInputStream(fis);

  byte[] privKeyBytes = new byte[(int) privKeyFile.length()];
  dis.read(privKeyBytes);
  dis.close();
  fis.close();

  String BEGIN = "-----BEGIN PRIVATE KEY-----";
  String END = "-----END PRIVATE KEY-----";
  String str = new String(privKeyBytes);
  if (str.contains(BEGIN) && str.contains(END)) {
    str = str.substring(BEGIN.length(), str.lastIndexOf(END));
  }

  KeyFactory fac = KeyFactory.getInstance("RSA");
  EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(Base64.decode(str));
  return fac.generatePrivate(privKeySpec);
}

PHP

การใช้ HMAC-SHA1 เป็นวิธีการลงนาม

require_once 'Zend/Oauth/Consumer.php';

session_start();

$CONSUMER_KEY = 'example.com';
$CONSUMER_SECRET = 'abc123doremi';

// Multi-scoped token.
$SCOPES = array(
  'https://docs.google.com/feeds/',
  'https://spreadsheets.google.com/feeds/'
);

$oauthOptions = array(
  'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
  'version' => '1.0',
  'consumerKey' => $CONSUMER_KEY,
  'consumerSecret' => $CONSUMER_SECRET,
  'signatureMethod' => 'HMAC-SHA1',
  'callbackUrl' => 'http://myapp.example.com/access_token.php',
  'requestTokenUrl' => 'https://www.google.com/accounts/OAuthGetRequestToken',
  'userAuthorizationUrl' => 'https://www.google.com/accounts/OAuthAuthorizeToken',
  'accessTokenUrl' => 'https://www.google.com/accounts/OAuthGetAccessToken'
);

$consumer = new Zend_Oauth_Consumer($oauthOptions);

// When using HMAC-SHA1, you need to persist the request token in some way.
// This is because you'll need the request token's token secret when upgrading
// to an access token later on. The example below saves the token object as a session variable.
if (!isset($_SESSION['ACCESS_TOKEN'])) {
  $_SESSION['REQUEST_TOKEN'] = serialize($consumer->getRequestToken(array('scope' => implode(' ', $SCOPES))));
}

การใช้ RSA-SHA1 เป็นวิธีการลงนาม

require_once 'Zend/Crypt/Rsa/Key/Private.php';
require_once 'Zend/Oauth/Consumer.php';

session_start();

$CONSUMER_KEY = 'example.com';
$SCOPE = 'https://docs.google.com/feeds/';

$oauthOptions = array(
  'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
  'version' => '1.0',
  'consumerKey' => $CONSUMER_KEY,
  'consumerSecret' => new Zend_Crypt_Rsa_Key_Private(file_get_contents(realpath('/path/to/yourRSAPrivateKey.pem'))),
  'signatureMethod' => 'RSA-SHA1',
  'callbackUrl' => 'http://myapp.example.com/access_token.php',
  'requestTokenUrl' => 'https://www.google.com/accounts/OAuthGetRequestToken',
  'userAuthorizationUrl' => 'https://www.google.com/accounts/OAuthAuthorizeToken',
  'accessTokenUrl' => 'https://www.google.com/accounts/OAuthGetAccessToken'
);

$consumer = new Zend_Oauth_Consumer($oauthOptions);

if (!isset($_SESSION['ACCESS_TOKEN'])) {
  $_SESSION['REQUEST_TOKEN'] = serialize($consumer->getRequestToken(array('scope' => $SCOPE)));
}

Python

การใช้ HMAC-SHA1 เป็นวิธีการลงนาม

หากคุณใช้คลาส v2.0 ขึ้นไปที่ใหม่กว่าซึ่งอิงตาม GDClient ให้ใช้สิ่งต่อไปนี้

import gdata.gauth
import gdata.docs.client

CONSUMER_KEY = 'example.com'
CONSUMER_SECRET = 'abc123doremi'
SCOPES = ['https://docs.google.com/feeds/', 'https://www.google.com/calendar/feeds/']  # example of a multi-scoped token

client = gdata.docs.client.DocsClient(source='yourCompany-YourAppName-v1')

oauth_callback_url = 'http://%s/get_access_token' % self.request.host
request_token = client.GetOAuthToken(
    SCOPES, oauth_callback_url, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)

# When using HMAC-SHA1, you need to persist the request_token in some way.
# You'll need the token secret when upgrading to an access token later on.
# In Google App Engine, you can use the AeSave helper:
# gdata.gauth.AeSave(request_token, 'myKey')

การใช้ RSA-SHA1 เป็นวิธีการลงนาม

...

f = open('/path/to/yourRSAPrivateKey.pem')
RSA_KEY = f.read()
f.close()

request_token = client.GetOAuthToken(SCOPES, oauth_callback_url, CONSUMER_KEY, rsa_private_key=RSA_KEY)

หรือหากคุณใช้คลาส v1.0 รุ่นเก่าที่อิงตาม GDataService การเรียกจะแตกต่างกันเล็กน้อย ดังนี้

import gdata.auth
import gdata.docs.service

CONSUMER_KEY = 'example.com'
CONSUMER_SECRET = 'abc123doremi'

client = gdata.docs.service.DocsService(source='yourCompany-YourAppName-v1')
client.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.HMAC_SHA1, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)

req_token = client.FetchOAuthRequestToken()
client.SetOAuthToken(req_token)

การใช้ RSA-SHA1 เป็นวิธีการลงนาม

...

f = open('/path/to/yourRSAPrivateKey.pem')
RSA_KEY = f.read()
f.close()

client = gdata.docs.service.DocsService(source='yourCompany-YourAppName-v1')
client.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.RSA_SHA1, CONSUMER_KEY, rsa_key=RSA_KEY)

SCOPES = ['https://docs.google.com/feeds/', 'https://www.google.com/calendar/feeds/']  # example of a multi-scoped token
req_token = client.FetchOAuthRequestToken(scopes=SCOPES)
client.SetOAuthToken(req_token)

.NET

การใช้ HMAC-SHA1 เป็นวิธีการลงนาม

using Google.GData.Client;

string CONSUMER_KEY = "example.com";
string CONSUMER_SECRET = "abc123doremi";

// Multi-scoped token.
string SCOPE = "https://www.google.com/calendar/feeds/ https://www.google.com/m8/feeds/";

OAuthParameters parameters = new OAuthParameters() {
  ConsumerKey = CONSUMER_KEY,
  ConsumerSecret = CONSUMER_SECRET,
  Scope = SCOPE,
  Callback = "http://myapp.example.com/access_token",
  SignatureMethod = "HMAC-SHA1"
}

OAuthUtil.GetUnauthorizedRequestToken(parameters);

การใช้ RSA-SHA1 เป็นวิธีการลงนาม

RSA-SHA1 is not supported yet.

การให้สิทธิ์โทเค็นคำขอ

หากต้องการให้สิทธิ์โทเค็นคำขอ แอปพลิเคชันของคุณต้องเปลี่ยนเส้นทางผู้ใช้ไปยัง URL ของ OAuthAuthorizeToken ซึ่งจะแจ้งให้ผู้ใช้เข้าสู่ระบบบัญชี Google ดูข้อมูลเพิ่มเติมเกี่ยวกับ OAuthAuthorizeToken URL ได้ที่การตรวจสอบสิทธิ์ OAuth สำหรับเว็บแอปพลิเคชันฉบับเต็ม

หากต้องการสร้าง OAuthAuthorizeToken URL ในแอปพลิเคชัน ให้ใช้ข้อมูลต่อไปนี้สำหรับแต่ละ Client Library โปรดทราบว่าตัวอย่างเหล่านี้ต่อยอดจากตัวอย่างก่อนหน้า

หลังจากสร้าง URL ของหน้าอนุมัติแล้ว แอปพลิเคชันจะใช้ URL ดังกล่าวได้หลายวิธีเพื่อส่งผู้ใช้ไปยังแฮนเดิลเลอร์ OAuthAuthorizeToken แนวทางที่พบบ่อยที่สุดคือการเปลี่ยนเส้นทางผู้ใช้หรือแสดงลิงก์ไปยังหน้าเว็บนั้น

Java

สำหรับ HMAC-SHA1

String approvalPageUrl = oauthHelper.createUserAuthorizationUrl(oauthParameters);
System.out.println(approvalPageUrl);

สำหรับ RSA-SHA1

String approvalPageUrl = oauthHelper.createUserAuthorizationUrl(oauthParameters);
System.out.println(approvalPageUrl);

PHP

// If on a G Suite domain, use your domain for the hd param (e.g. 'example.com').
$approvalUrl = $consumer->getRedirectUrl(array('hd' => 'default'));
echo "<a href=\"$approvalUrl\">Grant access</a>";

หรือจะเปลี่ยนเส้นทางไปยัง URL การอนุมัติก็ได้

// If on a G Suite domain, use your domain for the hd param (e.g. 'example.com').
$consumer->redirect(array('hd' => 'default'));

Python

หากคุณใช้คลาส v2.0 ขึ้นไปที่ใหม่กว่าซึ่งอิงตาม GDClient ให้ใช้สิ่งต่อไปนี้

# req_token is from previous call to client.GetOAuthToken()
domain = None  # If on a G Suite domain, use your domain (e.g. 'example.com').
self.redirect(request_token.generate_authorization_url(google_apps_domain=domain))

หากคุณใช้คลาส v1.0 รุ่นเก่าที่อิงตาม GDataService กระบวนการจะแตกต่างออกไปเล็กน้อย

# req_token is from previous call to client.FetchOAuthRequestToken()
oauth_callback_url = 'http://%s/get_access_token' % self.request.host
self.redirect(client.GenerateOAuthAuthorizationURL(callback_url=oauth_callback_url))

.NET

string authorizationUrl = OAuthUtil.CreateUserAuthorizationUrl(parameters);
Console.WriteLine(authorizationUrl);

การแยกโทเค็นจาก URL เรียกกลับ

เมื่อ Google เปลี่ยนเส้นทางกลับไปยังแอปพลิเคชันของคุณ ระบบจะเพิ่ม oauth_token ต่อท้าย URL "oauth_callback_url" เป็นพารามิเตอร์การค้นหา จากนั้นแอปพลิเคชันควรดึงค่าโทเค็นจากพารามิเตอร์การค้นหาของ URL และสร้างพารามิเตอร์ OAuth ขึ้นใหม่

ไลบรารีของไคลเอ็นต์มีเมธอดที่สะดวกสำหรับการแยก oauth_token ตัวอย่างเหล่านี้ต่อยอดจากตัวอย่างก่อนหน้า

Java

หากคุณเลือกที่จะเก็บข้อมูลลับของโทเค็นไว้ใน URL เรียกกลับ (เมื่อใช้ HMAC-SHA1) ให้ทำดังนี้

GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET);

GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthHmacSha1Signer());
oauthHelper.getOAuthParametersFromCallback(request.getQueryString(), oauthParameters);

ความแตกต่างเพียงอย่างเดียวของ RSA-SHA1 คือวิธีการลงนาม

GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);

PrivateKey privKey = getPrivateKey("/path/to/your/rsakey.pk8");

GoogleOAuthHelper oauthHelper = new GoogleOAuthHelper(new OAuthRsaSha1Signer(privKey));
oauthHelper.getOAuthParametersFromCallback(request.getQueryString(), oauthParameters);

PHP

ขั้นตอนนี้ไม่จำเป็นเมื่อใช้ไลบรารี PHP

Python

หากคุณใช้คลาส v2.0 ขึ้นไปที่ใหม่กว่าซึ่งอิงตาม GDClient ให้ใช้สิ่งต่อไปนี้

# Recall request_token. In Google App Engine, use AeLoad():
# saved_request_token = gdata.gauth.AeLoad('myKey')

request_token = gdata.gauth.AuthorizeRequestToken(saved_request_token, self.request.uri)

หากคุณใช้คลาส v1.0 รุ่นเก่าที่อิงตาม GDataService ให้ใช้

oauth_token = gdata.auth.OAuthTokenFromUrl(self.request.uri)
if oauth_token:
  oauth_token.secret = # TODO: recall saved request_token and set the token secret here.
  oauth_token.oauth_input_params = gdata.auth.OAuthInputParams(
      gdata.auth.OAuthSignatureMethod.HMAC_SHA1, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)
 client.SetOAuthToken(oauth_token)
else:
  print 'No oauth_token found in the URL'

กระบวนการสำหรับ RSA-SHA1 จะคล้ายกัน แต่ไม่มีข้อมูลลับของโทเค็น ดังนี้

oauth_token = gdata.auth.OAuthTokenFromUrl(self.request.uri)
if oauth_token:
  oauth_token.oauth_input_params = gdata.auth.OAuthInputParams(
      gdata.auth.OAuthSignatureMethod.RSA_SHA1, CONSUMER_KEY, rsa_key=RSA_KEY)
 client.SetOAuthToken(oauth_token)
else:
  print 'No oauth_token found in the URL'

.NET

หากเลือกที่จะเก็บข้อมูลลับของโทเค็นไว้ใน URL เรียกกลับ ให้ทำดังนี้

OAuthUtil.UpdateOAuthParametersFromCallback(url, parameters);

การอัปเกรดเป็นโทเค็นเพื่อการเข้าถึง

ขั้นตอนสุดท้ายในการแลกเปลี่ยนโทเค็น OAuth คือการอัปเกรดโทเค็นคำขอที่ได้รับอนุญาตเป็นโทเค็นเพื่อการเข้าถึงที่มีอายุยาวนานโดยใช้ OAuthGetAccessToken URL ตามที่อธิบายไว้ ในเอกสารประกอบการตรวจสอบสิทธิ์ OAuth สำหรับเว็บแอปพลิเคชันฉบับเต็ม

ตัวอย่างการใช้ไลบรารีของไคลเอ็นต์แต่ละรายการมีดังนี้

Java

String accessToken = oauthHelper.getAccessToken(oauthParameters);
// You can also pull the OAuth token string from the oauthParameters:
// String accessToken = oauthParameters.getOAuthToken();
System.out.println("OAuth Access Token: " + accessToken);

String accessTokenSecret = oauthParameters.getOAuthTokenSecret();
System.out.println("OAuth Access Token's Secret: " + accessTokenSecret);

PHP

if (!isset($_SESSION['ACCESS_TOKEN'])) {
  if (!empty($_GET) && isset($_SESSION['REQUEST_TOKEN'])) {
    $_SESSION['ACCESS_TOKEN'] = serialize($consumer->getAccessToken($_GET, unserialize($_SESSION['REQUEST_TOKEN'])));
  }
}

Python

หากคุณใช้คลาส v2.0 ขึ้นไปที่ใหม่กว่าซึ่งอิงตาม GDClient ให้ใช้สิ่งต่อไปนี้

# Upgrade the token and save in the user's datastore
access_token = client.GetAccessToken(request_token)

# If you're using Google App Engine, you can call the AeSave() method to save
# the access token under the current logged in user's account.
#gdata.gauth.AeSave(access_token, token_key)

หากคุณใช้คลาส v1.0 รุ่นเก่าที่อิงตาม GDataService ให้ใช้

access_token = client.UpgradeToOAuthAccessToken()  # calls SetOAuthToken() for you

หากคุณใช้ gdata.gauth.AeSave() ใน App Engine ระบบจะจัดเก็บโทเค็นและโทเค็นลับไว้ให้คุณภายใต้ผู้ใช้ที่เข้าสู่ระบบปัจจุบัน

.NET

OAuthUtil.GetAccessToken(parameters);

// If you want to extract the OAuth Token/TokenSecret from the OAuthParameters instance:
string accessToken = parameter.Token;
Console.WriteLine("OAuth Access Token: " + accessToken);

string accessTokenSecret = parameter.TokenSecret;
Console.WriteLine("OAuth Access Token's Secret: " + accessTokenSecret);

หมายเหตุ: หากใช้ HMAC-SHA1 โปรดบันทึกรหัสลับของโทเค็นเพื่อการเข้าถึง พร้อมกับค่าโทเค็นในฐานข้อมูล มิฉะนั้นคุณจะสร้างพารามิเตอร์ OAuth ขึ้นใหม่อย่างถูกต้องเพื่อใช้ในภายหลังไม่ได้

การใช้โทเค็นเพื่อการเข้าถึง

หลังจากได้รับโทเค็นการเข้าถึงแล้ว ให้ใช้การเรียกไลบรารีของไคลเอ็นต์ Google Data APIs มาตรฐานเพื่อโต้ตอบกับบริการ ไลบรารีจะ จัดการการลงนามคำขอและรวมส่วนหัวการให้สิทธิ์ที่ถูกต้องให้คุณ โดยปกติแล้ว คุณจะเรียกโทเค็นของผู้ใช้จากคุกกี้หรือฐานข้อมูล ตัวอย่างเหล่านี้แสดงวิธีสร้างพารามิเตอร์ OAuth ขึ้นใหม่และทำการเรียกไลบรารีไคลเอ็นต์

Java

หากใช้ HMAC-SHA1 ให้ทำดังนี้

  GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
  oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
  oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET);
  oauthParameters.setOAuthToken(ACCESS_TOKEN);
  oauthParameters.setOAuthTokenSecret(TOKEN_SECRET);

  DocsService client = new DocsService("yourCompany-YourAppName-v1");
  client.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());

  URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full");
  DocumentListFeed resultFeed = client.getFeed(feedUrl, DocumentListFeed.class);
  for (DocumentListEntry entry : resultFeed.getEntries()) {
    System.out.println(entry.getTitle().getPlainText());
  }
  

ความแตกต่างของ RSA-SHA1 คือคุณไม่จำเป็นต้องตั้งค่าลับของโทเค็นการเข้าถึง และการสร้างออบเจ็กต์ลายเซ็นจะแตกต่างกัน

  GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
  oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
  oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET);
  oauthParameters.setOAuthToken(ACCESS_TOKEN);

  PrivateKey privKey = getPrivateKey("/path/to/your/rsakey.pk8");  // See above for the defintion of getPrivateKey()

  DocsService client = new DocsService("yourCompany-YourAppName-v1");
  client.setOAuthCredentials(oauthParameters, new OAuthRsaSha1Signer(privKey));

  URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full");
  DocumentListFeed resultFeed = client.getFeed(feedUrl, DocumentListFeed.class);
  for (DocumentListEntry entry : resultFeed.getEntries()) {
    System.out.println(entry.getTitle().getPlainText());
  }
  

PHP

require_once 'Zend/Gdata/Docs.php';

if (isset($_SESSION['ACCESS_TOKEN'])) {
  $accessToken = unserialize($_SESSION['ACCESS_TOKEN']);
} else {
  exit;
}


/*  Or, you could set an existing token (say one stored from your database). For HMAC-SHA1:
$accessToken = new Zend_Oauth_Token_Access();
$accessToken->setToken('1/AQfoI-qJDqkvvkf216Gc2g');
$accessToken->setTokenSecret('2c26GLW250tZiQ');
*/

$httpClient = $accessToken->getHttpClient($oauthOptions);
$client = new Zend_Gdata_Docs($httpClient, "yourCompany-YourAppName-v1");

// Retrieve user's list of Google Docs
$feed = $client->getDocumentListFeed();
foreach ($feed->entries as $entry) {
  echo "$entry->title\n";
}

Python

ข้อมูลโค้ดนี้ถือว่าคุณได้ดึงข้อมูลโทเค็นเพื่อการเข้าถึงแล้ว (โดยใช้ HMAC-SHA1) และ กำลังเรียกคีย์/รหัสลับของโทเค็นนั้นเพื่อใช้ในภายหลัง

หากคุณใช้คลาส v2.0 ขึ้นไปที่ใหม่กว่าซึ่งอิงตาม GDClient ให้ใช้สิ่งต่อไปนี้

client = gdata.docs.client.DocsClient(source='yourCo-yourAppName-v1')
client.auth_token = gdata.gauth.OAuthHmacToken(CONSUMER_KEY, CONSUMER_SECRET, TOKEN,
                                               TOKEN_SECRET, gdata.gauth.ACCESS_TOKEN)
feed = client.GetDocList()
for entry in feed.entry:
  print entry.title.text

หากคุณใช้คลาส v1.0 รุ่นเก่าที่อิงตาม GDataService ให้ใช้

client = gdata.docs.service.DocsService(source='yourCompany-YourAppName-v1')
client.SetOAuthInputParameters(SIG_METHOD, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)

# the token key and secret should be recalled from your database
client.SetOAuthToken(gdata.auth.OAuthToken(key=TOKEN, secret=TOKEN_SECRET))

feed = client.GetDocumentListFeed()
for entry in feed.entry:
  print entry.title.text

.NET

หากใช้ HMAC-SHA1 ให้ทำดังนี้

OAuthParameters parameters = new OAuthParameters() {
  ConsumerKey = CONSUMER_KEY,
  ConsumerSecret = CONSUMER_SECRET,
  Token = ACCESS_TOKEN,
  TokenSecret = TOKEN_SECRET
}

GOAuthRequestFactory requestFactory = new GOAuthRequestFactory("writely", APPLICATION_NAME, parameters);

DocsService service = new DocsService(APPLICATION_NAME);
service.RequestFactory = requestFactory;

DocumentsListQuery query = new DocumentsListQuery();
DocumentsFeed feed = service.Query(query);
foreach (DocumentEntry entry in feed.Entries) {
  Console.WriteLine(entry.Title.Text);
}

ความแตกต่างของ RSA-SHA1 คือคุณไม่จำเป็นต้องตั้งค่าลับของโทเค็นการเข้าถึง และการสร้างออบเจ็กต์ลายเซ็นจะแตกต่างกัน

RSA-SHA1 is not supported yet.

แหล่งข้อมูลและตัวอย่าง OAuth แบบ 3 ทางเพิ่มเติม

กลับไปด้านบน

OAuth แบบ 2 ทาง

OAuth แบบ 2 ขาช่วยให้แอปพลิเคชันที่เชื่อถือได้เข้าถึงข้อมูล Google ของผู้ใช้ได้โดยไม่ต้องให้ผู้ใช้มีส่วนร่วมโดยตรง กลุ่มสำคัญ 2 กลุ่มที่ใช้ OAuth แบบ 2 ทางได้มีดังนี้

ผู้ดูแลระบบโดเมน G Suite: ผู้ดูแลระบบสามารถสร้างสคริปต์และแอปพลิเคชันที่กำหนดเองซึ่งจัดการข้อมูลผู้ใช้สำหรับโดเมนของตนผ่าน Google Data API ได้ ดูข้อมูลเกี่ยวกับการจัดการคีย์และข้อมูลลับที่เชื่อมโยงกับโดเมน G Suite และการให้สิทธิ์ควบคุมการเข้าถึงส่วนกลางได้ที่ "การจัดการคีย์และข้อมูลลับของ OAuth"

ผู้ให้บริการซอฟต์แวร์บุคคลที่สาม: ผู้ให้บริการอาจเสนอแอปพลิเคชันที่ใช้ OAuth แบบ 2 ขาเพื่อผสานรวมกับ G Suite คุณให้สิทธิ์เข้าถึงแอปพลิเคชันของบุคคลที่สามได้ในหน้าจัดการไคลเอ็นต์ API หรือโดยการติดตั้งจาก G Suite Marketplace

ไม่จำเป็นต้องใช้โทเค็นเพื่อการเข้าถึงตามขั้นตอนการให้สิทธิ์ปกติ (หรือที่เรียกว่า OAuth แบบ 3 ทาง)

ตัวอย่างไลบรารีของไคลเอ็นต์ต่อไปนี้แสดงวิธีกำหนดค่าไคลเอ็นต์ให้ใช้ OAuth แบบ 2 ขาโดยใช้ HMAC-SHA1

Java

import com.google.gdata.client.docs.*;
import com.google.gdata.client.authn.oauth.*;

String CONSUMER_KEY = "example.com";
String CONSUMER_SECRET = "abc123doremi";

GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CONSUMER_KEY);
oauthParameters.setOAuthConsumerSecret(CONSUMER_SECRET);

DocsService client = new DocsService("yourCompany-YourAppName-v1");
client.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());

// Retrieve user's list of Google Docs
String user = "any.user@anydomain.com";
URL feedUrl = new URL("https://docs.google.com/feeds/default/private/full" +
                      "?xoauth_requestor_id=" + user);

DocumentListFeed resultFeed = client.getFeed(feedUrl, DocumentListFeed.class);
for (DocumentListEntry entry : resultFeed.getEntries()) {
  System.out.println(entry.getTitle().getPlainText());
}

PHP

require_once 'Zend/Oauth/Consumer.php';
require_once 'Zend/Gdata/Docs.php';

$CONSUMER_KEY = 'example.com';
$CONSUMER_SECRET = 'abc123doremi';
$USER = 'any.user@anydomain.com';

$oauthOptions = array(
    'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
    'version' => '1.0',
    'signatureMethod' => 'HMAC-SHA1',
    'consumerKey' => $CONSUMER_KEY,
    'consumerSecret' => $CONSUMER_SECRET
);

$consumer = new Zend_Oauth_Consumer($oauthOptions);
$token = new Zend_Oauth_Token_Access();
$httpClient = $token->getHttpClient($oauthOptions);

$client = new Zend_Gdata_Docs($httpClient);

// Retrieve user's list of Google Docs
$feed = $client->getDocumentListFeed('https://docs.google.com/feeds/default/private/full?xoauth_requestor_id=' . urlencode($USER));
foreach ($feed->entries as $entry) {
  echo "$entry->title\n";
}

Python

หากคุณใช้คลาส v2.0 ขึ้นไปที่ใหม่กว่าซึ่งอิงตาม GDClient ให้ใช้สิ่งต่อไปนี้

import gdata.gauth
import gdata.docs.client

CONSUMER_KEY = 'example.com'
CONSUMER_SECRET = 'abc123doremi'
requestor_id = 'any.user@anydomain.com'

client = gdata.docs.client.DocsClient(source='yourCompany-YourAppName-v1')
client.auth_token = gdata.gauth.TwoLeggedOAuthHmacToken(
    CONSUMER_KEY, CONSUMER_SECRET, requestor_id)

# Retrieve user's list of Google Docs
feed = client.GetDocList()
for entry in feed.entry:
  print entry.title.text

หากคุณใช้คลาส v1.0 รุ่นเก่าที่อิงตาม GDataService ให้ใช้

import gdata.auth
import gdata.docs.service

CONSUMER_KEY = 'example.com'
CONSUMER_SECRET = 'abc123doremi'
SIG_METHOD = gdata.auth.OAuthSignatureMethod.HMAC_SHA1

requestor_id = 'any.user@anydomain.com'

client = gdata.docs.service.DocsService(source='yourCompany-YourAppName-v1')
client.SetOAuthInputParameters(SIG_METHOD, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET,
                               two_legged_oauth=True, requestor_id=requestor_id)

# Retrieve user's list of Google Docs
feed = client.GetDocumentListFeed()
for entry in feed.entry:
  print entry.title.text

# Change to another user on your domain
client.GetOAuthInputParameters().requestor_id = 'another.user@example.com'

.NET

using Google.GData.Client;
using Google.GData.Documents;

// Create an OAuth factory to use
GOAuthRequestFactory requestFactory = new GOAuthRequestFactory("writely", "yourCompany-YourAppName-v1");
requestFactory.ConsumerKey = "example.com";
requestFactory.ConsumerSecret = "abc123doremi";

String user = "any.user@anydomain.com";

DocumentsService client = new DocumentsService("yourCompany-YourAppName-v1");
client.RequestFactory = requestFactory;

// Retrieve user's list of Google Docs
DocumentsListQuery query = new DocumentsListQuery();
query.Uri = new OAuthUri("https://docs.google.com/feeds/default/private/full", user, requestFactory.ConsumerKey);

DocumentsFeed feed = client.Query(query);

foreach (DocumentEntry entry in feed.Entries)
{
  Console.WriteLine(entry.Title.Text);
}

แหล่งข้อมูลและตัวอย่าง OAuth แบบ 2 ทางเพิ่มเติม

การสร้างคีย์ส่วนตัวและใบรับรองสาธารณะที่ลงนามด้วยตนเอง

ระบบใช้คีย์ส่วนตัวเพื่อสร้างลายเซ็น ซึ่งต้องรวมไว้กับคำขอแต่ละรายการ Google ใช้คีย์สาธารณะที่ฝังอยู่ในใบรับรองเพื่อยืนยันลายเซ็น คีย์สาธารณะต้องเป็นคีย์ RSA ขนาด 1024 บิตที่เข้ารหัสในใบรับรอง X.509 ในรูปแบบ PEM คุณควรส่งใบรับรองให้ Google ในเวลาที่ลงทะเบียน

ส่วนต่อไปนี้จะแสดงตัวอย่างวิธีสร้างคีย์และใบรับรองโดยใช้เครื่องมือ 2 อย่าง ได้แก่ ยูทิลิตี OpenSSL และยูทิลิตี keytool ของ Java

ตัวอย่างเหล่านี้ไม่ได้เจาะจงสำหรับ Google Data API คุณสามารถใช้ยูทิลิตีเดียวกันเพื่อสร้างคีย์สำหรับวัตถุประสงค์ใดก็ได้

ตัวอย่างนี้ถือว่าบริษัทของคุณชื่อ My_Company ตั้งอยู่ที่ Mountain View รัฐแคลิฟอร์เนีย สหรัฐอเมริกา และมีชื่อโดเมนเป็น example.com

การสร้างคีย์โดยใช้ OpenSSL

หากต้องการสร้างคู่คีย์ RSA และใบรับรองที่เกี่ยวข้อง คุณสามารถใช้คำสั่งต่อไปนี้

# Generate the RSA keys and certificate
openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \
  '/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \
  myrsakey.pem -out /tmp/myrsacert.pem

คำเตือน: การใส่พารามิเตอร์ -nodes จะสร้างคีย์ส่วนตัวโดยไม่มีรหัสผ่านเพื่อปกป้องคีย์ อย่างไรก็ตาม คุณควรพิจารณาละเว้นพารามิเตอร์นี้เพื่อเพิ่มความปลอดภัย

-sha1 พารามิเตอร์ระบุว่าจะใช้คีย์เพื่อสร้างลายเซ็น SHA1

พารามิเตอร์ -subj ระบุตัวตนของแอปพลิเคชันที่ใบรับรองแสดง

พารามิเตอร์ -keyout จะระบุไฟล์ที่จะมีคีย์ ไฟล์นี้มีข้อมูลที่ละเอียดอ่อน จึงควรได้รับการปกป้องและไม่ควรแชร์กับใคร

พารามิเตอร์ -out จะระบุไฟล์ที่จะมีใบรับรองในรูปแบบ PEM (ซึ่งส่งให้ Google ได้ขณะลงทะเบียน)

สร้างคีย์สำหรับไคลเอ็นต์ .NET

เฟรมเวิร์ก .NET ไม่เข้าใจคีย์หรือใบรับรองที่จัดเก็บในรูปแบบ PEM ดังนั้น คุณจึงต้องทำตามขั้นตอนเพิ่มเติมเมื่อสร้างไฟล์ .pem แล้ว ดังนี้

openssl pkcs12 -export -in test_cert.pem -inkey myrsacert.pem -out myrsacert.pfx -name "Testing Certificate"

ขั้นตอนนี้จะสร้างไฟล์ PFX จากคีย์ส่วนตัวและใบรับรอง คุณสามารถนำเข้าไฟล์นี้ไปยังไลบรารีของไคลเอ็นต์ .NET เพื่อลงนามในคำขอที่ส่งไปยัง Google Data API แบบดิจิทัล

สร้างคีย์สำหรับไคลเอ็นต์ Java

ไคลเอ็นต์ Java ยอมรับคีย์ส่วนตัวในรูปแบบ PKCS#8 หลังจากสร้างคีย์/ใบรับรองโดยใช้วิธีการด้านบนแล้ว ให้สร้างไฟล์ .pk8 จากไฟล์ .pem ที่สร้างขึ้น

openssl pkcs8 -in myrsakey.pem -topk8 -nocrypt -out myrsakey.pk8

หรือคุณจะใช้ที่เก็บคีย์ Java และยูทิลิตี Keytool เพื่อสร้างคู่คีย์ RSA และใบรับรองที่เกี่ยวข้อง ก็ได้ ใช้คำสั่งต่อไปนี้

# Generate the RSA keys and certificate
keytool -genkey -v -alias Example -keystore ./Example.jks\
  -keyalg RSA -sigalg SHA1withRSA\
  -dname "CN=www.example.com, OU=Engineering, O=My_Company, L=Mountain  View, ST=CA, C=US"\
  -storepass changeme -keypass changeme

คำเตือน: "changeme" ไม่ใช่รหัสผ่านที่ดี นี่เป็นเพียงตัวอย่าง

พารามิเตอร์ -dname ระบุตัวตนของแอปพลิเคชันที่ใบรับรองแสดง พารามิเตอร์ -storepass ระบุรหัสผ่านเพื่อปกป้องคีย์สโตร์ พารามิเตอร์ -keypass จะระบุรหัสผ่านเพื่อปกป้องคีย์ส่วนตัว

หากต้องการเขียนใบรับรองลงในไฟล์ที่ใช้ในเครื่องมือ ManageDomains ได้ ให้ใช้คำสั่งต่อไปนี้

# Output the public certificate to a file
keytool -export -rfc -keystore ./Example.jks -storepass changeme \
  -alias Example -file mycert.pem

กลับไปด้านบน