ยืนยันโทเค็นสำหรับผู้ถือ

ระบบจะตั้งค่าโทเค็นสำหรับผู้ถือในส่วนหัว Authorization ของคำขอ HTTP สำหรับการดำเนินการในแอปทุกรายการ เช่น

POST /approve?expenseId=abc123 HTTP/1.1
Host: your-domain.com
Authorization: Bearer AbCdEf123456
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/1.0 (KHTML, like Gecko; Gmail Actions)

confirmed=Approved

สตริง "AbCdEf123456" ในตัวอย่างก่อนหน้านี้คือโทเค็นการให้สิทธิ์สำหรับผู้ถือ ซึ่งเป็นโทเค็นการเข้ารหัสลับที่ Google สร้างขึ้น โทเค็นสำหรับผู้ถือทั้งหมดที่ส่งมาพร้อมกับการดำเนินการจะมีช่อง azp (ผู้รับอนุญาต) ตั้งค่าเป็น gmail@system.gserviceaccount.com โดยช่อง audience จะระบุโดเมนของผู้ส่งเป็น URL ในรูปแบบ https:// เช่น หากอีเมลมาจาก noreply@example.com กลุ่มเป้าหมายจะเป็น https://example.com

หากใช้โทเค็นสำหรับผู้ถือ ให้ตรวจสอบว่าคำขอมาจาก Google และมีไว้สำหรับโดเมนของผู้ส่ง หากตรวจสอบโทเค็นไม่ได้ บริการควรตอบกลับคำขอด้วยรหัสการตอบกลับ HTTP 401 (Unauthorized)

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

ยืนยันโทเค็นสำหรับผู้ถือ

เราขอแนะนำให้ใช้ไลบรารีไคลเอ็นต์ Google API แบบโอเพนซอร์สเพื่อยืนยันโทเค็นสำหรับผู้ถือ ดังนี้

  • Java: https://github.com/google/google-api-java-client
  • Python: https://github.com/google/google-api-python-client
  • .NET: https://github.com/google/google-api-dotnet-client

Java

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;

import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.apache.ApacheHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;

public class TokenVerifier {
    // Bearer Tokens from Gmail Actions will always be issued to this authorized party.
    private static final String GMAIL_AUTHORIZED_PARTY = "gmail@system.gserviceaccount.com";

    // Intended audience of the token, based on the sender's domain
    private static final String AUDIENCE = "https://example.com";

    public static void main(String[] args) throws GeneralSecurityException, IOException {
        // Get this value from the request's Authorization HTTP header.
        // For example, for "Authorization: Bearer AbCdEf123456" use "AbCdEf123456"
        String bearerToken = "AbCdEf123456";

        GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new ApacheHttpTransport(), new JacksonFactory())
                .setAudience(Collections.singletonList(AUDIENCE))
                .build();

        GoogleIdToken idToken = verifier.verify(bearerToken);
        if (idToken == null || !idToken.getPayload().getAuthorizedParty().equals(GMAIL_AUTHORIZED_PARTY)) {
            System.out.println("Invalid token");
            System.exit(-1);
        }

        // Token originates from Google and is targeted to a specific client.
        System.out.println("The token is valid");

        System.out.println("Token details:");
        System.out.println(idToken.getPayload().toPrettyString());
    }
}

Python

import sys

from oauth2client import client

# Bearer Tokens from Gmail Actions will always be issued to this authorized party.
GMAIL_AUTHORIZED_PARTY = 'gmail@system.gserviceaccount.com'

# Intended audience of the token, based on the sender's domain
AUDIENCE = 'https://example.com'

try:
  # Get this value from the request's Authorization HTTP header.
  # For example, for "Authorization: Bearer AbCdEf123456" use "AbCdEf123456"
  bearer_token = 'AbCdEf123456'

  # Verify valid token, signed by google.com, intended for a third party.
  token = client.verify_id_token(bearer_token, AUDIENCE)
  print('Token details: %s' % token)

  if token['azp'] != GMAIL_AUTHORIZED_PARTY:
    sys.exit('Invalid authorized party')
except:
  sys.exit('Invalid token')

# Token originates from Google and is targeted to a specific client.
print('The token is valid')