승인 토큰 가져오기

토큰이란 무엇인가요?

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

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

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

JSON 웹 토큰에 관한 자세한 내용은 Fleet Engine 기본사항JSON 웹 토큰을 참고하세요.

클라이언트가 토큰을 가져오는 방법

운전자나 소비자가 적절한 앱을 사용해 앱에 로그인하면 해당 기기에서 실행되는 모든 업데이트는 적절한 승인 토큰이 있어야 합니다. 권한을 부여할 수 있습니다.

개발자는 클라이언트 구현에서 다음을 실행할 수 있는 기능을 제공해야 합니다.

  • 서버에서 JSON 웹 토큰을 가져옵니다.
  • 토큰이 만료될 때까지 토큰을 재사용하여 토큰 새로고침을 최소화합니다.
  • 토큰이 만료되면 새로고침합니다.

GMTDAuthorization 프로토콜은 위치 업데이트 시간에 JSON 웹 토큰을 가져옵니다. GMTD AuthorizationContext 객체에 기반합니다. 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 초기화