Bearer Token은 모든 인앱 액션 HTTP 요청의 Authorization 헤더에 설정됩니다. 예를 들면 다음과 같습니다.
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에서 생성한 암호화 토큰입니다.
작업과 함께 전송되는 모든 Bearer 토큰에는 azp (승인된 당사자) 필드가 gmail@system.gserviceaccount.com으로 설정되어 있으며, audience 필드에는 발신자 도메인이 https:// 형식의 URL로 지정되어 있습니다. 예를 들어 이메일이 noreply@example.com에서 전송된 경우 수신자는 https://example.com입니다.
전달자 토큰을 사용하는 경우 요청이 Google에서 전송되었으며 발신자 도메인을 대상으로 하는지 확인합니다. 토큰이 확인되지 않으면 서비스는 HTTP 응답 코드 401 (Unauthorized)로 요청에 응답해야 합니다.
전달자 토큰은 OAuth V2 표준의 일부이며 Google API에서 널리 채택되고 있습니다.
전달자 토큰 확인
서비스는 오픈소스 Google API 클라이언트 라이브러리를 사용하여 전달자 토큰을 확인하는 것이 좋습니다.
- 자바: https://github.com/google/google-api-java-client
- Python: https://github.com/google/google-api-python-client
자바
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')