取得授權權杖

什麼是權杖?

對於從低信任環境發出的 API 方法呼叫,Fleet Engine 會規定 使用由適當服務帳戶簽署的 JSON Web Token (JWT)。 信任度低的環境包括智慧型手機和瀏覽器。JWT 會在伺服器上產生,而伺服器是完全信任的環境。系統會為 JWT 簽署、加密,並將其傳遞給用戶端,以便後續的伺服器互動,直到 JWT 到期或不再有效為止。

您的後端應使用 標準的應用程式預設憑證機制。廠牌 請務必使用適當服務帳戶簽署的 JWT。換 服務帳戶角色清單,請參閱 Fleet Engine 服務帳戶角色 詳情請參閱 Fleet Engine 基本概念一文。

相對的,後端應針對 Fleet Engine 進行驗證與授權 使用標準應用程式預設憑證 機制

如要進一步瞭解 JSON Web Token,請參閱 Fleet Engine 重點中的「JSON Web Token」。

用戶端如何取得權杖?

駕駛或消費者使用適當的 驗證憑證,任何從該裝置發出的更新都必須使用 取得適當的授權權杖,向 Fleet Engine 和 授予所需的應用程式權限

身為開發人員,客戶導入作業必須具有 :

  • 從伺服器擷取 JSON Web Token。
  • 在權杖到期前重複使用,盡量減少權杖重新整理次數。
  • 在權杖到期時重新整理。

GMTDAuthorization 通訊協定會在位置更新時擷取 JSON Web 權杖 根據 GMTD AuthorizationContext 物件而定SDK 必須將權杖與更新資訊封裝,再傳送至 Fleet Engine。 請確定伺服器端導入作業可發出符記, 初始化 SDK 中

如要進一步瞭解 Fleet Engine 所需的符記,請參閱 Fleet Engine 的「發出 JSON Web Token」一文。

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