取得授權權杖

什麼是權杖?

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

後端應使用標準的應用程式預設憑證機制,針對 Fleet Engine 進行驗證和授權。廠牌 請務必使用適當服務帳戶簽署的 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

後續步驟

初始化驅動程式 SDK