توکن چیست؟
موتور ناوگان (Fleet Engine) برای فراخوانی متدهای API از محیطهای کماعتماد (مثل تلفنهای هوشمند و مرورگرها) نیاز به استفاده از توکنهای وب JSON (JWT) دارد.
یک JWT از سرور شما سرچشمه میگیرد، امضا و رمزگذاری میشود و برای تعاملات بعدی با سرور به کلاینت ارسال میشود تا زمانی که منقضی شود یا دیگر معتبر نباشد.
جزئیات کلیدی
- از اعتبارنامههای پیشفرض برنامه برای تأیید اعتبار و مجوزدهی در برابر Fleet Engine استفاده کنید.
- از یک حساب کاربری سرویس مناسب برای امضای JWTها استفاده کنید. به نقشهای حساب کاربری سرویس Fleet Engine در اصول اولیه Fleet Engine مراجعه کنید.
برای اطلاعات بیشتر در مورد JSON Web Tokens، به JSON Web Tokens در Fleet Engine Essentials مراجعه کنید.
مشتریان چگونه توکن دریافت میکنند؟
به محض اینکه راننده یا مصرفکننده با استفاده از اطلاعات احراز هویت مناسب وارد برنامه شما میشود، هرگونه بهروزرسانی که از آن دستگاه صادر شود باید از توکنهای مجوز مناسب استفاده کند که مجوزهای برنامه را به Fleet Engine منتقل میکند.
به عنوان توسعهدهنده، پیادهسازی کلاینت شما باید قابلیت انجام موارد زیر را فراهم کند:
- یک JSON Web Token از سرور خود دریافت کنید.
- برای به حداقل رساندن بهروزرسانیهای توکن، از توکن تا زمان انقضای آن مجدداً استفاده کنید.
- وقتی توکن منقضی شد، آن را بهروزرسانی کنید.
پروتکل GMTDAuthorization توکنهای وب JSON را در زمان بهروزرسانی موقعیت مکانی بر اساس شیء GMTD AuthorizationContext دریافت میکند. SDK باید توکنها را به همراه اطلاعات بهروزرسانی برای ارسال به Fleet Engine بستهبندی کند. قبل از مقداردهی اولیه SDK، مطمئن شوید که پیادهسازی سمت سرور شما میتواند توکنها را صادر کند.
برای جزئیات توکنهای مورد انتظار Fleet Engine، به بخش صدور توکنهای وب JSON برای Fleet Engine مراجعه کنید.
providerID همان شناسه پروژه پروژه Google Cloud شما است. برای اطلاعات بیشتر در مورد راهاندازی پروژه Google Cloud، به بخش «ایجاد پروژه موتور ناوگان» مراجعه کنید.
مثالی از یک دریافتکننده توکن احراز هویت
مثال زیر یک ارائهدهنده توکن مجوز را پیادهسازی میکند:
سویفت
/*
* 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()
}
}
هدف-سی
/*
* 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