Uzyskaj tokeny autoryzacji

Co to jest token?

W przypadku wywołań metod interfejsu API z środowisk o niskim poziomie zaufania usługa Fleet Engine wymaga korzystania z tokenów sieciowych JSON (JWT) podpisanych odpowiednim kontem usługi. Środowiska o niskim poziomie zaufania to smartfony i przeglądarki. Token JWT pochodzi z serwera, który jest pełnowymiarowym zaufanym środowiskiem. JWT jest podpisywany, szyfrowany i przekazywany do klienta na potrzeby kolejnych interakcji z serwerem, dopóki nie wygaśnie lub nie straci ważności.

Twój backend powinien uwierzytelniać i autoryzować się w Fleet Engine za pomocą standardowych mechanizmów domyślnych danych logowania aplikacji. Marka używaj tokenów JWT, które zostały podpisane przez odpowiednie konto usługi. Listę ról kont usług znajdziesz w artykule Podstawy Fleet Engine, w sekcji Role kont usług Fleet Engine.

Z kolei backend powinien uwierzytelniać i autoryzować się w ramach Fleet Engine, korzystając ze standardowych mechanizmów danych logowania aplikacji.

Więcej informacji o tokenach sieciowych JSON znajdziesz w artykule na temat tokenów sieciowych JSON w Informacje o usłudze Fleet Engine.

Jak klienci otrzymują tokeny?

Gdy kierowca lub klient zaloguje się w aplikacji za pomocą odpowiednich danych logowania, wszystkie aktualizacje wysyłane z tego urządzenia muszą używać odpowiednich tokenów autoryzacji, które przekazują Fleet Engine uprawnienia aplikacji.

Jako deweloper powinieneś zadbać o to, aby implementacja klienta umożliwiała:

  • Pobierz token sieciowy JSON ze swojego serwera.
  • Aby zminimalizować częstotliwość odświeżania tokenów, używaj tokena do momentu jego wygaśnięcia.
  • Odśwież token po jego wygaśnięciu.

Protokół GMTDAuthorization pobiera tokeny sieciowe JSON w momencie aktualizacji lokalizacji na podstawie obiektu GMTD AuthorizationContext. Pakiet SDK musi spakować tokeny z informacjami o aktualizacji, które mają zostać wysłane do Fleet Engine. Zanim zainicjujesz pakiet SDK, upewnij się, że implementacja po stronie serwera może wydawać tokeny.

Szczegółowe informacje o tokenach wymaganych przez Fleet Engine znajdziesz w artykule Wydawanie tokenów sieciowych JSON na temat Fleet Engine.

Identyfikator dostawcy jest taki sam jak identyfikator projektu Twojego projektu Google Cloud. Informacje o konfigurowaniu projektu Google Cloud znajdziesz w artykule Tworzenie projektu Fleet Engine.

Przykład modułu pobierania tokenów uwierzytelniania

Poniższy przykład pokazuje implementację interfejsu GMTDAuthorization protokołu.

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

Co dalej?

Inicjowanie pakietu Driver SDK