מה זה טוקן?
כדי להפעיל שיטות API מסביבות עם רמת אמינות נמוכה (סמארטפונים ודפדפנים), צריך להשתמש ב-Fleet Engine בטוקנים של JSON Web (JWT).
מקור ה-JWT הוא בשרת שלכם, הוא חתום, מוצפן ומועבר ללקוח לאינטראקציות הבאות עם השרת עד שהוא פג תוקף או לא תקף יותר.
פרטים חשובים
- משתמשים ב-Application Default Credentials כדי לבצע אימות והרשאה מול Fleet Engine.
- משתמשים בחשבון שירות מתאים כדי לחתום על אסימוני JWT. תפקידים בחשבון השירות ב-Fleet Engine במאמר הסבר בסיסי על Fleet Engine.
מידע נוסף על אסימוני אינטרנט מסוג JSON מופיע בקטע אסימוני אינטרנט מסוג JSON במאמר מידע בסיסי על Fleet Engine.
איך הלקוחות מקבלים אסימונים?
אחרי שנהג או צרכן מתחברים לאפליקציה באמצעות פרטי הכניסה המתאימים, כל העדכונים שמונפקים מהמכשיר הזה חייבים להשתמש באסימוני הרשאה מתאימים, שמעבירים ל-Fleet Engine את ההרשאות של האפליקציה.
כמפתחים, אתם צריכים להטמיע בצד הלקוח את היכולת לבצע את הפעולות הבאות:
- אחזור של JSON Web Token מהשרת.
- כדי לצמצם את מספר הרענונים של האסימון, כדאי להשתמש בו שוב עד שיפוג התוקף שלו.
- מרעננים את הטוקן כשתוקפו פג.
הפרוטוקול GMTDAuthorization מאחזר אסימוני אינטרנט מסוג JSON בזמן עדכון לגבי מיקום, על סמך האובייקט GMTD AuthorizationContext. ה-SDK צריך לארוז את הטוקנים עם פרטי העדכון כדי לשלוח אותם ל-Fleet Engine.
לפני שמפעילים את ה-SDK, חשוב לוודא שההטמעה בצד השרת יכולה להנפיק טוקנים.
במאמר הנפקת אסימוני אינטרנט מסוג JSON ל-Fleet Engine מפורטים האסימונים ש-Fleet Engine מצפה לקבל.
הערך של providerID זהה לערך של מזהה פרויקט בפרויקט ב-Google Cloud. איך מגדירים פרויקט בענן ב-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