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