取得授權權杖

什麼是符記?

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

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

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

如要進一步瞭解 JSON Web Token,請參閱 JSON Web Token ( Fleet Engine Essentials

用戶端如何取得權杖?

駕駛或消費者使用適當的 驗證憑證,任何從該裝置發出的更新都必須使用 取得適當的授權權杖,向 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 專案

驗證權杖擷取工具範例

以下範例實作授權權杖供應工具:

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

後續步驟

初始化 Consumer SDK