รับรองคำขอแบบดิจิทัลด้วยคีย์ API
คุณอาจต้องใช้ลายเซ็นดิจิทัลนอกเหนือจากคีย์ API เพื่อตรวจสอบสิทธิ์คำขอ ทั้งนี้ขึ้นอยู่กับการใช้งานของคุณ ดูข้อมูลเพิ่มเติมได้ที่บทความต่อไปนี้
วิธีการทำงานของลายเซ็นดิจิทัล
ลายเซ็นดิจิทัลใช้คีย์ลับลงนาม URL ซึ่งมีอยู่ในคอนโซล Google Cloud ซึ่งเป็นคีย์ส่วนตัวที่แชร์ระหว่างคุณกับ Google เท่านั้น และเป็นคีย์เฉพาะสำหรับโปรเจ็กต์ของคุณ
กระบวนการลงชื่อจะใช้อัลกอริทึมการเข้ารหัสเพื่อรวม URL และข้อมูลลับที่ใช้ร่วมกัน ลายเซ็นที่ไม่ซ้ำกันที่ได้จะช่วยให้เซิร์ฟเวอร์ของ Google ยืนยันได้ว่าเว็บไซต์ที่สร้างคำขอโดยใช้คีย์ API ของคุณได้รับอนุญาตให้ดำเนินการดังกล่าว
จำกัดคำขอที่ไม่ได้ลงชื่อ
โปรดทำดังนี้เพื่อให้มั่นใจว่าคีย์ API ของคุณยอมรับเฉพาะคำขอที่ลงชื่อแล้ว
- ไปที่หน้าโควต้า Google Maps Platform ในคอนโซล Cloud
- จากรายการแบบเลื่อนลงของโปรเจ็กต์ ให้เลือกโปรเจ็กต์ที่คุณใช้เมื่อสร้างคีย์ API สำหรับแอปพลิเคชันหรือเว็บไซต์
- จากรายการแบบเลื่อนลง API ให้เลือก Maps Static API หรือ Street View Static API
- ขยายส่วนคำขอที่ไม่ได้ลงชื่อ
- ในตารางชื่อโควต้า ให้คลิกแก้ไขข้างโควต้าที่ต้องการแก้ไข เช่น คำขอที่ไม่ได้ลงชื่อต่อวัน
- ในแผงแก้ไขขีดจำกัดโควต้า ให้อัปเดตขีดจำกัดโควต้า
- คลิกบันทึก
การลงนามคำขอ
การลงนามคำขอประกอบด้วยขั้นตอนต่อไปนี้
- ขั้นตอนที่ 1: รับคีย์ลับลงนาม URL
- ขั้นตอนที่ 2: สร้างคำขอที่ไม่ได้ลงนาม
- ขั้นตอนที่ 3: สร้างคำขอที่ลงนาม
ขั้นตอนที่ 1: รับคีย์ลับลงนาม URL
วิธีรับคีย์ลับลงนาม URL ของโปรเจ็กต์
- ไปที่หน้าข้อมูลเข้าสู่ระบบของ Google Maps Platform ในคอนโซล Cloud
- เลือกเมนูแบบเลื่อนลงของโปรเจ็กต์ แล้วเลือกโปรเจ็กต์เดียวกับที่ใช้เมื่อสร้างคีย์ API สำหรับ
- เลื่อนลงไปที่การ์ดเครื่องมือสร้างข้อมูลลับ ช่องคีย์ลับปัจจุบันจะมีคีย์ลับลงนาม URL ปัจจุบันของคุณ
- หน้านี้ยังมีวิดเจ็ตรับรอง URL เลยที่ช่วยให้คุณรับรองคำขอโดยอัตโนมัติได้โดยใช้ข้อมูลลับสำหรับการรับรองปัจจุบัน เลื่อนลงไปที่การ์ดลงชื่อ URL เลยเพื่อเข้าถึง
หากต้องการรับคีย์ลับลงนาม URL ใหม่ ให้เลือกสร้างคีย์ลับใหม่ ข้อมูลลับก่อนหน้าจะหมดอายุหลังจากที่คุณสร้างข้อมูลลับใหม่แล้ว 24 ชั่วโมง หลังจากผ่านไป 24 ชั่วโมง คำขอที่มีข้อมูลลับเก่าจะใช้ไม่ได้อีกต่อไป
ขั้นตอนที่ 2: สร้างคำขอที่ไม่ได้ลงชื่อ
อักขระที่ไม่ได้แสดงในตารางด้านล่างต้องเข้ารหัส URL ดังนี้
| ตั้งค่า | อักขระ | การใช้ URL |
|---|---|---|
| ตัวอักษรและตัวเลขคละกัน | a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 | สตริงข้อความ การใช้รูปแบบ (http) พอร์ต (8080) ฯลฯ |
| ไม่ได้จอง | - _ . ~ | สตริงข้อความ |
| จองแล้ว | ! * ' ( ) ; : @ & = + $ , / ? % # [ ] | อักขระควบคุมและ/หรือสตริงข้อความ |
เช่นเดียวกับอักขระใดๆ ในชุดสงวนไว้ หากส่งผ่านภายในสตริงข้อความ ดูข้อมูลเพิ่มเติมได้ที่อักขระพิเศษ
สร้าง URL คำขอที่ไม่ได้ลงชื่อโดยไม่มีลายเซ็น ดูวิธีการได้ในเอกสารประกอบสำหรับนักพัฒนาซอฟต์แวร์ต่อไปนี้
อย่าลืมใส่คีย์ API ในพารามิเตอร์ key ด้วย เช่น
https://maps.googleapis.com/maps/api/staticmap?center=Z%C3%BCrich&size=400x400&key=YOUR_API_KEY
สร้างคำขอที่ลงนามแล้ว
สำหรับ Use Case แบบครั้งเดียว เช่น การโฮสต์รูปภาพ Maps Static API หรือ Street View Static API แบบง่ายในหน้าเว็บ หรือเพื่อวัตถุประสงค์ในการแก้ปัญหา คุณสามารถสร้างลายเซ็นดิจิทัลโดยอัตโนมัติได้โดยใช้วิดเจ็ตลงชื่อ URL เลยที่มีอยู่
สำหรับคำขอที่สร้างขึ้นแบบไดนามิก คุณต้องใช้การรับรองฝั่งเซิร์ฟเวอร์ ซึ่งต้องมีขั้นตอนกลางเพิ่มเติมอีก 2-3 ขั้นตอน
ไม่ว่าจะด้วยวิธีใด คุณควรได้ URL คำขอที่มีพารามิเตอร์ signature ต่อท้าย เช่น
https://maps.googleapis.com/maps/api/staticmap?center=Z%C3%BCrich&size=400x400&key=YOUR_API_KEY
&signature=BASE64_SIGNATUREการใช้วิดเจ็ต "ลงชื่อ URL เลย"
วิธีสร้างลายเซ็นดิจิทัลด้วยคีย์ API โดยใช้วิดเจ็ตลงชื่อ URL เลยในคอนโซล Google Cloud มีดังนี้
- ค้นหาวิดเจ็ตลงนาม URL เลยตามที่อธิบายไว้ในขั้นตอนที่ 1: รับคีย์ลับลงนาม URL
- ในช่อง URL ให้วาง URL คำขอที่ไม่ได้ลงชื่อจากขั้นตอนที่ 2: สร้างคำขอที่ไม่ได้ลงชื่อ
- ช่อง URL ที่รับรองแล้วของคุณที่ปรากฏขึ้นจะมี URL ที่รับรองแบบดิจิทัลของคุณ อย่าลืมทำสำเนา
สร้างลายเซ็นดิจิทัลฝั่งเซิร์ฟเวอร์
เมื่อเทียบกับวิดเจ็ตรับรอง URL เลย คุณจะต้องดำเนินการเพิ่มเติมอีก 2-3 อย่างเมื่อสร้างลายเซ็นดิจิทัลฝั่งเซิร์ฟเวอร์ ดังนี้
-
ตัดส่วนรูปแบบโปรโตคอลและโฮสต์ของ URL ออก โดยเหลือไว้เฉพาะเส้นทางและการค้นหา ดังนี้
-
คีย์ลับลงนาม URL ที่แสดงจะเข้ารหัสใน Base64 ที่แก้ไขแล้วสำหรับ URL
เนื่องจากไลบรารีการเข้ารหัสส่วนใหญ่กำหนดให้คีย์อยู่ในรูปแบบไบต์ดิบ คุณจึงอาจต้องถอดรหัสคีย์ลับลงนาม URL เป็นรูปแบบดิบดั้งเดิมก่อนลงนาม
- ลงนามคำขอที่ตัดข้อมูลออกข้างต้นโดยใช้ HMAC-SHA1
-
เนื่องจากไลบรารีการเข้ารหัสส่วนใหญ่จะสร้างลายเซ็นในรูปแบบไบต์ดิบ คุณจึงต้องแปลงลายเซ็นไบนารีที่ได้โดยใช้ Base64 ที่แก้ไขแล้วสำหรับ URL เพื่อแปลงเป็นสิ่งที่ส่งผ่านภายใน URL ได้
-
ต่อท้ายลายเซ็นที่เข้ารหัส Base64 กับ URL คำขอที่ไม่ได้ลงชื่อเดิมในพารามิเตอร์
signatureเช่นhttps://maps.googleapis.com/maps/api/staticmap?center=Z%C3%BCrich&size=400x400&key=YOUR_API_KEY &signature=BASE64_SIGNATURE
/maps/api/staticmap?center=Z%C3%BCrich&size=400x400&key=YOUR_API_KEY
ดูตัวอย่างที่แสดงวิธีใช้การรับรอง URL โดยใช้โค้ดฝั่งเซิร์ฟเวอร์ได้ที่โค้ดตัวอย่างสำหรับการรับรอง URL ด้านล่าง
โค้ดตัวอย่างสำหรับการลงชื่อ URL
ส่วนต่อไปนี้จะแสดงวิธีใช้การลงนาม URL โดยใช้โค้ดฝั่งเซิร์ฟเวอร์ URL ควรได้รับการลงนามฝั่งเซิร์ฟเวอร์เสมอเพื่อหลีกเลี่ยงการเปิดเผยคีย์ลับลงนาม URL แก่ผู้ใช้
Python
ตัวอย่างด้านล่างใช้ไลบรารี Python มาตรฐานเพื่อลงชื่อ URL (ดาวน์โหลดโค้ด)
#!/usr/bin/python # -*- coding: utf-8 -*- """ Signs a URL using a URL signing secret """ import hashlib import hmac import base64 import urllib.parse as urlparse def sign_url(input_url=None, secret=None): """ Sign a request URL with a URL signing secret. Usage: from urlsigner import sign_url signed_url = sign_url(input_url=my_url, secret=SECRET) Args: input_url - The URL to sign secret - Your URL signing secret Returns: The signed request URL """ if not input_url or not secret: raise Exception("Both input_url and secret are required") url = urlparse.urlparse(input_url) # We only need to sign the path+query part of the string url_to_sign = url.path + "?" + url.query # Decode the private key into its binary format # We need to decode the URL-encoded private key decoded_key = base64.urlsafe_b64decode(secret) # Create a signature using the private key and the URL-encoded # string using HMAC SHA1. This signature will be binary. signature = hmac.new(decoded_key, str.encode(url_to_sign), hashlib.sha1) # Encode the binary signature into base64 for use within a URL encoded_signature = base64.urlsafe_b64encode(signature.digest()) original_url = url.scheme + "://" + url.netloc + url.path + "?" + url.query # Return signed URL return original_url + "&signature=" + encoded_signature.decode() if __name__ == "__main__": input_url = input("URL to Sign: ") secret = input("URL signing secret: ") print("Signed URL: " + sign_url(input_url, secret))
Java
ตัวอย่างด้านล่างใช้คลาส java.util.Base64 ที่พร้อมใช้งานตั้งแต่ JDK 1.8 เวอร์ชันเก่าอาจต้องใช้ Apache Commons หรือที่คล้ายกัน
(ดาวน์โหลดโค้ด)
import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; // JDK 1.8 only - older versions may need to use Apache Commons or similar. import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.net.URL; import java.io.BufferedReader; import java.io.InputStreamReader; public class UrlSigner { // Note: Generally, you should store your private key someplace safe // and read them into your code private static String keyString = "YOUR_PRIVATE_KEY"; // The URL shown in these examples is a static URL which should already // be URL-encoded. In practice, you will likely have code // which assembles your URL from user or web service input // and plugs those values into its parameters. private static String urlString = "YOUR_URL_TO_SIGN"; // This variable stores the binary key, which is computed from the string (Base64) key private static byte[] key; public static void main(String[] args) throws IOException, InvalidKeyException, NoSuchAlgorithmException, URISyntaxException { BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); String inputUrl, inputKey = null; // For testing purposes, allow user input for the URL. // If no input is entered, use the static URL defined above. System.out.println("Enter the URL (must be URL-encoded) to sign: "); inputUrl = input.readLine(); if (inputUrl.equals("")) { inputUrl = urlString; } // Convert the string to a URL so we can parse it URL url = new URL(inputUrl); // For testing purposes, allow user input for the private key. // If no input is entered, use the static key defined above. System.out.println("Enter the Private key to sign the URL: "); inputKey = input.readLine(); if (inputKey.equals("")) { inputKey = keyString; } UrlSigner signer = new UrlSigner(inputKey); String request = signer.signRequest(url.getPath(),url.getQuery()); System.out.println("Signed URL :" + url.getProtocol() + "://" + url.getHost() + request); } public UrlSigner(String keyString) throws IOException { // Convert the key from 'web safe' base 64 to binary keyString = keyString.replace('-', '+'); keyString = keyString.replace('_', '/'); System.out.println("Key: " + keyString); // Base64 is JDK 1.8 only - older versions may need to use Apache Commons or similar. this.key = Base64.getDecoder().decode(keyString); } public String signRequest(String path, String query) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, URISyntaxException { // Retrieve the proper URL components to sign String resource = path + '?' + query; // Get an HMAC-SHA1 signing key from the raw key bytes SecretKeySpec sha1Key = new SecretKeySpec(key, "HmacSHA1"); // Get an HMAC-SHA1 Mac instance and initialize it with the HMAC-SHA1 key Mac mac = Mac.getInstance("HmacSHA1"); mac.init(sha1Key); // compute the binary signature for the request byte[] sigBytes = mac.doFinal(resource.getBytes()); // base 64 encode the binary signature // Base64 is JDK 1.8 only - older versions may need to use Apache Commons or similar. String signature = Base64.getEncoder().encodeToString(sigBytes); // convert the signature to 'web safe' base 64 signature = signature.replace('+', '-'); signature = signature.replace('/', '_'); return resource + "&signature=" + signature; } }
Node.js
ตัวอย่างด้านล่างใช้โมดูล Node แบบเนทีฟเพื่อรับรอง URL (ดาวน์โหลดโค้ด)
'use strict' const crypto = require('crypto'); const url = require('url'); /** * Convert from 'web safe' base64 to true base64. * * @param {string} safeEncodedString The code you want to translate * from a web safe form. * @return {string} */ function removeWebSafe(safeEncodedString) { return safeEncodedString.replace(/-/g, '+').replace(/_/g, '/'); } /** * Convert from true base64 to 'web safe' base64 * * @param {string} encodedString The code you want to translate to a * web safe form. * @return {string} */ function makeWebSafe(encodedString) { return encodedString.replace(/\+/g, '-').replace(/\//g, '_'); } /** * Takes a base64 code and decodes it. * * @param {string} code The encoded data. * @return {string} */ function decodeBase64Hash(code) { // "new Buffer(...)" is deprecated. Use Buffer.from if it exists. return Buffer.from ? Buffer.from(code, 'base64') : new Buffer(code, 'base64'); } /** * Takes a key and signs the data with it. * * @param {string} key Your unique secret key. * @param {string} data The url to sign. * @return {string} */ function encodeBase64Hash(key, data) { return crypto.createHmac('sha1', key).update(data).digest('base64'); } /** * Sign a URL using a secret key. * * @param {string} path The url you want to sign. * @param {string} secret Your unique secret key. * @return {string} */ function sign(path, secret) { const uri = url.parse(path); const safeSecret = decodeBase64Hash(removeWebSafe(secret)); const hashedSignature = makeWebSafe(encodeBase64Hash(safeSecret, uri.path)); return url.format(uri) + '&signature=' + hashedSignature; }
C#
ตัวอย่างด้านล่างใช้ไลบรารี System.Security.Cryptography เริ่มต้นเพื่อลงชื่อในคำขอ URL
โปรดทราบว่าเราต้องแปลงการเข้ารหัส Base64 เริ่มต้นเพื่อใช้เวอร์ชันที่ปลอดภัยสำหรับ URL
(ดาวน์โหลดโค้ด)
using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Web; namespace SignUrl { public struct GoogleSignedUrl { public static string Sign(string url, string keyString) { ASCIIEncoding encoding = new ASCIIEncoding(); // converting key to bytes will throw an exception, need to replace '-' and '_' characters first. string usablePrivateKey = keyString.Replace("-", "+").Replace("_", "/"); byte[] privateKeyBytes = Convert.FromBase64String(usablePrivateKey); Uri uri = new Uri(url); byte[] encodedPathAndQueryBytes = encoding.GetBytes(uri.LocalPath + uri.Query); // compute the hash HMACSHA1 algorithm = new HMACSHA1(privateKeyBytes); byte[] hash = algorithm.ComputeHash(encodedPathAndQueryBytes); // convert the bytes to string and make url-safe by replacing '+' and '/' characters string signature = Convert.ToBase64String(hash).Replace("+", "-").Replace("/", "_"); // Add the signature to the existing URI. return uri.Scheme+"://"+uri.Host+uri.LocalPath + uri.Query +"&signature=" + signature; } } class Program { static void Main() { // Note: Generally, you should store your private key someplace safe // and read them into your code const string keyString = "YOUR_PRIVATE_KEY"; // The URL shown in these examples is a static URL which should already // be URL-encoded. In practice, you will likely have code // which assembles your URL from user or web service input // and plugs those values into its parameters. const string urlString = "YOUR_URL_TO_SIGN"; string inputUrl = null; string inputKey = null; Console.WriteLine("Enter the URL (must be URL-encoded) to sign: "); inputUrl = Console.ReadLine(); if (inputUrl.Length == 0) { inputUrl = urlString; } Console.WriteLine("Enter the Private key to sign the URL: "); inputKey = Console.ReadLine(); if (inputKey.Length == 0) { inputKey = keyString; } Console.WriteLine(GoogleSignedUrl.Sign(inputUrl,inputKey)); } } }
ตัวอย่างในภาษาอื่นๆ
ดูตัวอย่างที่ครอบคลุมภาษาอื่นๆ ได้ในโปรเจ็กต์ url-signing
การแก้ปัญหา
หากคำขอมีลายเซ็นที่ไม่ถูกต้อง API จะแสดงข้อผิดพลาด HTTP 403 (Forbidden) ข้อผิดพลาดนี้มักเกิดขึ้นหากความลับในการลงชื่อที่ใช้ไม่ได้ลิงก์กับคีย์ API ที่ส่งมา หรือหากอินพุตที่ไม่ใช่ ASCII ไม่ได้เข้ารหัส URL ก่อนลงชื่อ
หากต้องการแก้ปัญหา ให้คัดลอก URL คำขอ ตัดพารามิเตอร์การค้นหา signature ออก แล้วสร้างลายเซ็นที่ถูกต้องอีกครั้งโดยทำตามวิธีการด้านล่าง
วิธีสร้างลายเซ็นดิจิทัลด้วยคีย์ API โดยใช้วิดเจ็ตลงชื่อ URL เลยในคอนโซล Google Cloud มีดังนี้
- ค้นหาวิดเจ็ตลงนาม URL เลยตามที่อธิบายไว้ในขั้นตอนที่ 1: รับคีย์ลับลงนาม URL
- ในช่อง URL ให้วาง URL คำขอที่ไม่ได้ลงชื่อจากขั้นตอนที่ 2: สร้างคำขอที่ไม่ได้ลงชื่อ
- ช่อง URL ที่รับรองแล้วของคุณที่ปรากฏขึ้นจะมี URL ที่รับรองแบบดิจิทัลของคุณ อย่าลืมทำสำเนา