승인 토큰 가져오기

토큰이란 무엇인가요?

신뢰 수준이 낮은 환경의 API 메서드 호출의 경우 Fleet Engine은 적절한 서비스 계정으로 서명된 JSON 웹 토큰(JWT)을 사용해야 합니다. 신뢰도가 낮은 환경에는 스마트폰과 브라우저가 포함됩니다. JWT는 완전히 신뢰할 수 있는 환경인 서버에서 시작됩니다. JWT는 만료되거나 더 이상 유효하지 않을 때까지 서명되고 암호화된 후 후속 서버 상호작용을 위해 클라이언트에게 전달됩니다.

백엔드는 표준 애플리케이션 기본 사용자 인증 정보 메커니즘을 사용하여 Fleet Engine에 대해 인증하고 승인해야 합니다. 적절한 서비스 계정으로 서명된 JWT를 사용해야 합니다. 서비스 계정 역할 목록은 Fleet Engine 기본사항Fleet Engine 서비스 계정 역할을 참조하세요.

반대로 백엔드는 표준 애플리케이션 기본 사용자 인증 정보 메커니즘을 사용하여 Fleet Engine에 대해 인증 및 승인해야 합니다.

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 프로젝트 만들기를 참조하세요.

인증 토큰 가져오기의 예

다음 예에서는 GMTDAuthorization 프로토콜의 구현을 보여줍니다.

Swift

import GoogleRidesharingDriver

private let providerURL = "INSERT_YOUR_TOKEN_PROVIDER_URL"

class SampleAccessTokenProvider: NSObject, GMTDAuthorization {
  private struct AuthToken {
    // The cached vehicle token.
    let token: String
    // Keep track of when the token expires for caching.
    let expiration: TimeInterval
    // Keep track of the vehicle ID the cached token is for.
    let vehicleID: String
  }

  enum AccessTokenError: Error {
    case missingAuthorizationContext
    case missingData
  }

  private var authToken: AuthToken?

  func fetchToken(
    with authorizationContext: GMTDAuthorizationContext?,
    completion: @escaping GMTDAuthTokenFetchCompletionHandler
  ) {
    // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.
    guard let authorizationContext = authorizationContext else {
      completion(nil, AccessTokenError.missingAuthorizationContext)
      return
    }
    let vehicleID = authorizationContext.vehicleID

    // If appropriate, use the cached token.
    if let authToken = authToken,
      authToken.expiration > Date.now.timeIntervalSince1970 && authToken.vehicleID == vehicleID
    {
      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 vehicleTokenKey = "VEHICLE_TOKEN_KEY"
      let tokenExpirationKey = "TOKEN_EXPIRATION"
      guard let data = data,
        let fetchData = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
        let token = fetchData[vehicleTokenKey] as? String,
        let expiration = fetchData[tokenExpirationKey] as? Double
      else {
        completion(nil, AccessTokenError.missingData)
        return
      }

      strongSelf.authToken = AuthToken(
        token: token, expiration: expiration, vehicleID: vehicleID)
      completion(token, nil)
    }
    task.resume()
  }
}

Objective-C

#import "SampleAccessTokenProvider.h"
#import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>

// SampleAccessTokenProvider.h
@interface SampleAccessTokenProvider : NSObject<GMTDAuthorization>
@end

static NSString *const PROVIDER_URL = @"INSERT_YOUR_TOKEN_PROVIDER_URL";

// SampleAccessTokenProvider.m
@implementation SampleAccessTokenProvider{
  // The cached vehicle token.
  NSString *_cachedVehicleToken;
  // Keep track of the vehicle ID the cached token is for.
  NSString *_lastKnownVehicleID;
  // Keep track of when tokens expire for caching.
  NSTimeInterval _tokenExpiration;
}

-   (void)fetchTokenWithContext:(nullable GMTDAuthorizationContext *)authorizationContext
                   completion:(nonnull GMTDAuthTokenFetchCompletionHandler)completion {

  if (!completion) {
   NSAssert(NO, @"%s encountered an unexpected nil completion.", __PRETTY_FUNCTION__);
   return;
  }

  // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.
  NSString *vehicleID = authorizationContext.vehicleID;
  if (!vehicleID) {
    NSAssert(NO, @"Vehicle ID is missing from authorizationContext.");
    return;
  }

  // Clear cached vehicle token if vehicle ID has changed.
  if (![_lastKnownVehicleID isEqual:vehicleID]) {
    _tokenExpiration = 0.0;
    _cachedVehicleToken = nil;
  }
  _lastKnownVehicleID = vehicleID;

  // Clear cached vehicletoken if it has expired.
  if ([[NSDate date] timeIntervalSince1970] > _tokenExpiration) {
    _cachedVehicleToken = nil;
  }

  // If appropriate, use the cached token.
  if (_cachedVehicleToken) {
    completion(_cachedVehicleToken, 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 *vehicleTokenKey = @"VEHICLE_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->_cachedVehicleToken = JSONResponse[vehicleTokenKey];
          completion(JSONResponse[vehicleTokenKey], 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

다음 단계

Driver SDK 초기화