승인 토큰 가져오기
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
토큰이란 무엇인가요?
Fleet Engine에서는 신뢰도가 낮은 환경(스마트폰 및 브라우저)에서 API 메서드를 호출할 때 JSON 웹 토큰(JWT)을 사용해야 합니다.
JWT는 서버에서 생성되고 서명, 암호화되어 만료되거나 더 이상 유효하지 않을 때까지 후속 서버 상호작용을 위해 클라이언트에 전달됩니다.
주요 세부정보
JSON 웹 토큰에 관한 자세한 내용은 Fleet Engine 필수사항의 JSON 웹 토큰을 참고하세요.
클라이언트가 토큰을 가져오는 방법
운전자 또는 소비자가 적절한 인증 사용자 인증 정보를 사용하여 앱에 로그인하면 해당 기기에서 발행된 업데이트는 앱의 권한을 Fleet Engine에 전달하는 적절한 승인 토큰을 사용해야 합니다.
개발자로서 클라이언트 구현은 다음을 실행할 수 있는 기능을 제공해야 합니다.
- 서버에서 JSON 웹 토큰을 가져옵니다.
- 토큰이 만료될 때까지 재사용하여 토큰 새로고침을 최소화합니다.
- 토큰이 만료되면 토큰을 새로고침합니다.
GMTDAuthorization
프로토콜은 GMTD AuthorizationContext
객체를 기반으로 위치 업데이트 시간에 JSON 웹 토큰을 가져옵니다. SDK는 업데이트 정보와 함께 토큰을 패키징하여 Fleet Engine에 전송해야 합니다.
SDK를 초기화하기 전에 서버 측 구현에서 토큰을 발급할 수 있는지 확인합니다.
Fleet Engine에서 예상하는 토큰에 관한 자세한 내용은 Fleet Engine용 JSON 웹 토큰 발급을 참고하세요.
providerID는 Google Cloud 프로젝트의 프로젝트 ID와 동일합니다. Google Cloud 프로젝트 설정에 관한 자세한 내용은 Fleet Engine 프로젝트 만들기를 참고하세요.
인증 토큰 가져오기의 예
다음 예에서는 승인 토큰 제공자를 구현합니다.
Swift
/*
* SampleAccessTokenProvider.swift
*/
import GoogleRidesharingConsumer
private let providerURL = "INSERT_YOUR_TOKEN_PROVIDER_URL"
class SampleAccessTokenProvider: NSObject, GMTCAuthorization {
private struct AuthToken {
// The cached trip token.
let token: String
// Keep track of when the token expires for caching.
let expiration: TimeInterval
// Keep track of the trip ID the cached token is for.
let tripID: String
}
enum AccessTokenError: Error {
case missingAuthorizationContext
case missingData
}
private var authToken: AuthToken?
func fetchToken(
with authorizationContext: GMTCAuthorizationContext?,
completion: @escaping GMTCAuthTokenFetchCompletionHandler
) {
// Get the trip ID from the authorizationContext. This is set by the Consumer SDK.
guard let authorizationContext = authorizationContext else {
completion(nil, AccessTokenError.missingAuthorizationContext)
return
}
let tripID = authorizationContext.tripID
// If appropriate, use the cached token.
if let authToken = authToken,
authToken.expiration > Date.now.timeIntervalSince1970 && authToken.tripID == tripID
{
completion(authToken.token, nil)
return
}
// Otherwise, try to fetch a new token from your server.
let request = URLRequest(url: URL(string: providerURL))
let task = URLSession.shared.dataTask(with: request) { [weak self] data, _, error in
guard let strongSelf = self else { return }
guard error == nil else {
completion(nil, error)
return
}
// Replace the following key values with the appropriate keys based on your
// server's expected response.
let tripTokenKey = "TRIP_TOKEN_KEY"
let tokenExpirationKey = "TOKEN_EXPIRATION"
guard let data = data,
let fetchData = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let token = fetchData[tripTokenKey] as? String,
let expiration = fetchData[tokenExpirationKey] as? Double
else {
completion(nil, AccessTokenError.missingData)
return
}
strongSelf.authToken = AuthToken(token: token, expiration: expiration, tripID: tripID)
completion(token, nil)
}
task.resume()
}
}
Objective-C
/*
* SampleAccessTokenProvider.h
*/
#import <Foundation/Foundation.h>
#import <GoogleRidesharingConsumer/GoogleRidesharingConsumer.h>
NS_ASSUME_NONNULL_BEGIN
@interface SampleAccessTokenProvider : NSObject <GMTCAuthorization>
@end
NS_ASSUME_NONNULL_END
/*
* SampleAccessTokenProvider.m
*/
#import "SampleAccessTokenProvider.h"
#import "GoogleRidesharingConsumer/GoogleRidesharingConsumer.h"
static NSString *const PROVIDER_URL = @"INSERT_YOUR_TOKEN_PROVIDER_URL";
// SampleAccessTokenProvider.m
@implementation SampleAccessTokenProvider {
// The cached token with claims to the current trip.
NSString *_cachedTripToken;
// Keep track of the Trip ID the cached token is for.
NSString *_lastKnownTripID;
// Keep track of when tokens expire for caching.
NSTimeInterval _tokenExpiration;
}
- (void)fetchTokenWithContext:(nullable GMTCAuthorizationContext *)authorizationContext
completion:(nonnull GMTCAuthTokenFetchCompletionHandler)completion {
// Get the trip ID from the authorizationContext. This is set by the Consumer SDK.
NSString *tripID = authorizationContext.tripID;
// Clear cached trip token if trip ID has changed.
if (![_lastKnownTripID isEqual:tripID]) {
_tokenExpiration = 0.0;
_cachedTripToken = nil;
}
_lastKnownTripID = tripID;
// Clear cached tripToken if it has expired.
if ([[NSDate date] timeIntervalSince1970] > _tokenExpiration) {
_cachedTripToken = nil;
}
// If appropriate, use the cached token.
if (_cachedTripToken) {
completion(_cachedTripToken, nil);
return;
}
// Otherwise, try to fetch a new token from your server.
NSURL *requestURL = [NSURL URLWithString:PROVIDER_URL];
NSMutableURLRequest *request =
[[NSMutableURLRequest alloc] initWithURL:requestURL];
request.HTTPMethod = @"GET";
// Replace the following key values with the appropriate keys based on your
// server's expected response.
NSString *tripTokenKey = @"TRIP_TOKEN_KEY";
NSString *tokenExpirationKey = @"TOKEN_EXPIRATION";
__weak typeof(self) weakSelf = self;
void (^handler)(NSData *_Nullable data, NSURLResponse *_Nullable response,
NSError *_Nullable error) =
^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
typeof(self) strongSelf = weakSelf;
if (error) {
completion(nil, error);
return;
}
NSError *JSONError;
NSMutableDictionary *JSONResponse =
[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&JSONError];
if (JSONError) {
completion(nil, JSONError);
return;
} else {
// Sample code only. No validation logic.
id expirationData = JSONResponse[tokenExpirationKey];
if ([expirationData isKindOfClass:[NSNumber class]]) {
NSTimeInterval expirationTime = ((NSNumber *)expirationData).doubleValue;
strongSelf->_tokenExpiration = [[NSDate date] timeIntervalSince1970] + expirationTime;
}
strongSelf->_cachedTripToken = JSONResponse[tripTokenKey];
completion(JSONResponse[tripTokenKey], nil);
}
};
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *mainQueueURLSession =
[NSURLSession sessionWithConfiguration:config delegate:nil
delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *task = [mainQueueURLSession dataTaskWithRequest:request completionHandler:handler];
[task resume];
}
@end
다음 단계
소비자 SDK 초기화
달리 명시되지 않는 한 이 페이지의 콘텐츠에는 Creative Commons Attribution 4.0 라이선스에 따라 라이선스가 부여되며, 코드 샘플에는 Apache 2.0 라이선스에 따라 라이선스가 부여됩니다. 자세한 내용은 Google Developers 사이트 정책을 참조하세요. 자바는 Oracle 및/또는 Oracle 계열사의 등록 상표입니다.
최종 업데이트: 2025-08-31(UTC)
[null,null,["최종 업데이트: 2025-08-31(UTC)"],[[["\u003cp\u003eFleet Engine utilizes JSON Web Tokens (JWTs) for API method calls originating from low-trust environments like smartphones and browsers, ensuring secure communication.\u003c/p\u003e\n"],["\u003cp\u003eYour backend server, a trusted environment, generates and signs these JWTs, which are then passed to clients for server interactions.\u003c/p\u003e\n"],["\u003cp\u003eClients, such as driver or consumer apps, need to fetch, reuse, and refresh these JWTs to maintain authorized access to Fleet Engine functionalities.\u003c/p\u003e\n"],["\u003cp\u003eThe provided code examples demonstrate how to implement an authorization token provider in Swift and Objective-C for fetching and managing JWTs within your client application.\u003c/p\u003e\n"]]],["Fleet Engine utilizes JSON Web Tokens (JWTs) for API calls from low-trust environments. Developers must fetch signed, encrypted JWTs from their servers and provide them to clients. Tokens should be reused until expiration and then refreshed. Clients obtain tokens upon user login, ensuring updates are authorized. The `GMTDAuthorization` protocol manages token fetching at update times. The provided code examples demonstrate how to implement a token fetcher in Swift and Objective-C, caching and refreshing tokens as needed. The providerID is equivalent to the project ID.\n"],null,["What is a token?\n\nFleet Engine requires the use of **JSON Web Tokens** (JWTs) for API method calls\nfrom **low-trust environments**: smartphones and browsers.\n\nA JWT originates on your server, is signed, encrypted, and passed to the client\nfor subsequent server interactions until it expires or is no longer valid.\n\n**Key details**\n\n- Use [Application Default Credentials](https://google.aip.dev/auth/4110) to authenticate and authorize against Fleet Engine.\n- Use an appropriate service account to sign JWTs. See [Fleet Engine serviceaccount](/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/service-accounts#fleet_engine_service_account_roles) roles in **Fleet Engine Basics**.\n\nFor more information about JSON Web Tokens, see [JSON Web Tokens](/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/jwt) in\n**Fleet Engine Essentials**.\n\nHow clients get tokens?\n\nOnce a driver or consumer logs in to your app using the appropriate\nauthentication credentials, any updates issued from that device must use\nappropriate authorization tokens, which communicates to Fleet Engine the\npermissions for the app.\n\nAs the developer, your client implementation should provide the ability to\ndo the following:\n\n- Fetch a JSON Web Token from your server.\n- Reuse the token until it expires to minimize token refreshes.\n- Refresh the token when it expires.\n\nThe `GMTDAuthorization` protocol fetches JSON Web tokens at location update time\nbased on the `GMTD AuthorizationContext` object. The SDK\nmust package the tokens with the update information to send to Fleet Engine.\nMake sure that your server-side implementation can issue tokens before\ninitializing the SDK.\n\nFor details of the tokens expected by Fleet Engine, see\n[Issue JSON Web Tokens](/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/issue-jwt) for Fleet Engine.\n\nThe providerID is the same as the **Project ID** of your Google Cloud\nProject. For information on setting up the Google Cloud Project, see\n[Create your Fleet Engine project](/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/create-project).\n\nExample of an authentication token fetcher\n\nThe following example implements an authorization token provider: \n\nSwift \n\n /*\n * SampleAccessTokenProvider.swift\n */\n import GoogleRidesharingConsumer\n\n private let providerURL = \"INSERT_YOUR_TOKEN_PROVIDER_URL\"\n\n class SampleAccessTokenProvider: NSObject, GMTCAuthorization {\n private struct AuthToken {\n // The cached trip token.\n let token: String\n // Keep track of when the token expires for caching.\n let expiration: TimeInterval\n // Keep track of the trip ID the cached token is for.\n let tripID: String\n }\n\n enum AccessTokenError: Error {\n case missingAuthorizationContext\n case missingData\n }\n\n private var authToken: AuthToken?\n\n func fetchToken(\n with authorizationContext: GMTCAuthorizationContext?,\n completion: @escaping GMTCAuthTokenFetchCompletionHandler\n ) {\n // Get the trip ID from the authorizationContext. This is set by the Consumer SDK.\n guard let authorizationContext = authorizationContext else {\n completion(nil, AccessTokenError.missingAuthorizationContext)\n return\n }\n let tripID = authorizationContext.tripID\n\n // If appropriate, use the cached token.\n if let authToken = authToken,\n authToken.expiration \u003e Date.now.timeIntervalSince1970 && authToken.tripID == tripID\n {\n completion(authToken.token, nil)\n return\n }\n\n // Otherwise, try to fetch a new token from your server.\n let request = URLRequest(url: URL(string: providerURL))\n let task = URLSession.shared.dataTask(with: request) { [weak self] data, _, error in\n guard let strongSelf = self else { return }\n guard error == nil else {\n completion(nil, error)\n return\n }\n\n // Replace the following key values with the appropriate keys based on your\n // server's expected response.\n let tripTokenKey = \"TRIP_TOKEN_KEY\"\n let tokenExpirationKey = \"TOKEN_EXPIRATION\"\n guard let data = data,\n let fetchData = try? JSONSerialization.jsonObject(with: data) as? [String: Any],\n let token = fetchData[tripTokenKey] as? String,\n let expiration = fetchData[tokenExpirationKey] as? Double\n else {\n completion(nil, AccessTokenError.missingData)\n return\n }\n\n strongSelf.authToken = AuthToken(token: token, expiration: expiration, tripID: tripID)\n completion(token, nil)\n }\n task.resume()\n }\n }\n\nObjective-C \n\n /*\n * SampleAccessTokenProvider.h\n */\n #import \u003cFoundation/Foundation.h\u003e\n #import \u003cGoogleRidesharingConsumer/GoogleRidesharingConsumer.h\u003e\n\n NS_ASSUME_NONNULL_BEGIN\n\n @interface SampleAccessTokenProvider : NSObject \u003cGMTCAuthorization\u003e\n\n @end\n\n NS_ASSUME_NONNULL_END\n\n /*\n * SampleAccessTokenProvider.m\n */\n #import \"SampleAccessTokenProvider.h\"\n #import \"GoogleRidesharingConsumer/GoogleRidesharingConsumer.h\"\n\n static NSString *const PROVIDER_URL = @\"INSERT_YOUR_TOKEN_PROVIDER_URL\";\n\n // SampleAccessTokenProvider.m\n @implementation SampleAccessTokenProvider {\n // The cached token with claims to the current trip.\n NSString *_cachedTripToken;\n // Keep track of the Trip ID the cached token is for.\n NSString *_lastKnownTripID;\n // Keep track of when tokens expire for caching.\n NSTimeInterval _tokenExpiration;\n }\n\n - (void)fetchTokenWithContext:(nullable GMTCAuthorizationContext *)authorizationContext\n completion:(nonnull GMTCAuthTokenFetchCompletionHandler)completion {\n // Get the trip ID from the authorizationContext. This is set by the Consumer SDK.\n NSString *tripID = authorizationContext.tripID;\n\n // Clear cached trip token if trip ID has changed.\n if (![_lastKnownTripID isEqual:tripID]) {\n _tokenExpiration = 0.0;\n _cachedTripToken = nil;\n }\n _lastKnownTripID = tripID;\n\n // Clear cached tripToken if it has expired.\n if ([[NSDate date] timeIntervalSince1970] \u003e _tokenExpiration) {\n _cachedTripToken = nil;\n }\n\n // If appropriate, use the cached token.\n if (_cachedTripToken) {\n completion(_cachedTripToken, nil);\n return;\n }\n // Otherwise, try to fetch a new token from your server.\n NSURL *requestURL = [NSURL URLWithString:PROVIDER_URL];\n NSMutableURLRequest *request =\n [[NSMutableURLRequest alloc] initWithURL:requestURL];\n request.HTTPMethod = @\"GET\";\n\n // Replace the following key values with the appropriate keys based on your\n // server's expected response.\n NSString *tripTokenKey = @\"TRIP_TOKEN_KEY\";\n NSString *tokenExpirationKey = @\"TOKEN_EXPIRATION\";\n\n __weak typeof(self) weakSelf = self;\n void (^handler)(NSData *_Nullable data, NSURLResponse *_Nullable response,\n NSError *_Nullable error) =\n ^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {\n typeof(self) strongSelf = weakSelf;\n if (error) {\n completion(nil, error);\n return;\n }\n\n NSError *JSONError;\n NSMutableDictionary *JSONResponse =\n [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&JSONError];\n\n if (JSONError) {\n completion(nil, JSONError);\n return;\n } else {\n // Sample code only. No validation logic.\n id expirationData = JSONResponse[tokenExpirationKey];\n if ([expirationData isKindOfClass:[NSNumber class]]) {\n NSTimeInterval expirationTime = ((NSNumber *)expirationData).doubleValue;\n strongSelf-\u003e_tokenExpiration = [[NSDate date] timeIntervalSince1970] + expirationTime;\n }\n strongSelf-\u003e_cachedTripToken = JSONResponse[tripTokenKey];\n completion(JSONResponse[tripTokenKey], nil);\n }\n };\n NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];\n NSURLSession *mainQueueURLSession =\n [NSURLSession sessionWithConfiguration:config delegate:nil\n delegateQueue:[NSOperationQueue mainQueue]];\n NSURLSessionDataTask *task = [mainQueueURLSession dataTaskWithRequest:request completionHandler:handler];\n [task resume];\n }\n\n @end\n\nWhat's Next\n\n[Initialize the Consumer SDK](/maps/documentation/mobility/journey-sharing/on-demand/ios/init-sdk)"]]