ما هو الرمز المميّز؟
تتطلّب أداة Fleet Engine استخدام رموز JSON المميّزة للويب (JWT) لطلبات واجهة برمجة التطبيقات من البيئات ذات مستوى الثقة المنخفض: الهواتف الذكية والمتصفّحات.
يبدأ JWT على خادمك، ويتم توقيعه وتشفيره وتمريره إلى العميل لتفاعلات الخادم اللاحقة إلى أن تنتهي صلاحيته أو لم يعُد صالحًا.
التفاصيل الرئيسية
- استخدِم بيانات الاعتماد التلقائية للتطبيق للمصادقة والحصول على الإذن في Fleet Engine.
- استخدِم حساب خدمة مناسبًا لتوقيع ملفات JWT. اطّلِع على أدوار حساب خدمة Fleet Engine في أساسيات Fleet Engine.
لمزيد من المعلومات عن رموز JSON المميّزة للويب، يُرجى الاطّلاع على رموز JSON المميّزة للويب في أساسيات Fleet Engine.
كيف يحصل العملاء على الرموز؟
بعد أن يسجّل السائق أو المستهلك الدخول إلى تطبيقك باستخدام بيانات اعتماد مصادقة مناسبة، يجب أن تستخدم أي تعديلات يتم إجراؤها من هذا الجهاز رموزاً مميّزة مناسبة للسماح، والتي تُرسِل إلى Fleet Engine أذونات التطبيق.
بصفتك المطوّر، يجب أن يتيح لك تنفيذ العميل تنفيذ ما يلي:
- استرِجِع رمز JSON المميّز للويب من خادمك.
- أعِد استخدام الرمز المميّز إلى أن تنتهي صلاحيته لتقليل عمليات إعادة تحميل الرمز المميّز.
- أعِد تحميل الرمز المميّز عند انتهاء صلاحيته.
يُستخدَم بروتوكول GMTDAuthorization
لجلب رموز JSON المميّزة للويب في وقت تعديل الموقع الجغرافي
استنادًا إلى عنصر GMTD AuthorizationContext
. يجب أن تحزِّم حزمة SDK علامات الاعتماد مع معلومات التحديث لإرسالها إلى Fleet Engine.
تأكَّد من أنّ التنفيذ من جهة الخادم يمكنه إصدار الرموز المميّزة قبل
بدء حزمة تطوير البرامج (SDK).
للاطّلاع على تفاصيل الرموز المميّزة التي تتوقّعها Fleet Engine، يُرجى الاطّلاع على مقالة إصدار الرموز المميّزة بتنسيق JSON للويب في 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