获取授权令牌
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
什么是令牌?
对于来自低信任环境(智能手机和浏览器)的 API 方法调用,Fleet Engine 要求使用 JSON Web 令牌 (JWT)。
JWT 源自您的服务器,经过签名和加密后传递给客户端,以供后续服务器交互使用,直到过期或不再有效为止。
关键细节
如需详细了解 JSON Web 令牌,请参阅 Fleet Engine 基础知识中的 JSON Web 令牌。
客户如何获取令牌?
司机或消费者使用相应的身份验证凭据登录您的应用后,从该设备发出的任何更新都必须使用相应的授权令牌,以便向 Fleet Engine 传达应用的权限。
作为开发者,您的客户端实现应能够执行以下操作:
- 从服务器获取 JSON Web 令牌。
- 重复使用令牌,直到其过期,以尽可能减少令牌刷新次数。
- 在令牌过期时刷新令牌。
GMTDAuthorization
协议会在位置更新时根据 GMTD AuthorizationContext
对象提取 JSON Web 令牌。SDK 必须将令牌与更新信息打包在一起,然后发送到 Fleet Engine。
请确保您的服务器端实现可以在初始化 SDK 之前签发令牌。
如需详细了解 Fleet Engine 期望的令牌,请参阅为 Fleet Engine 签发 JSON Web 令牌。
providerID 与您的 Google Cloud 项目的项目 ID 相同。如需了解如何设置 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
后续步骤
初始化 Driver SDK
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-08-31。
[null,null,["最后更新时间 (UTC):2025-08-31。"],[[["\u003cp\u003eFleet Engine utilizes JSON Web Tokens (JWTs) for API method calls originating from low-trust environments like smartphones and browsers, ensuring secure communication.\u003c/p\u003e\n"],["\u003cp\u003eYour backend server, a trusted environment, generates and signs these JWTs, which are then passed to clients for server interactions.\u003c/p\u003e\n"],["\u003cp\u003eClients, such as driver or consumer apps, need to fetch, reuse, and refresh these JWTs to maintain authorized access to Fleet Engine functionalities.\u003c/p\u003e\n"],["\u003cp\u003eThe provided code examples demonstrate how to implement a token fetcher using the \u003ccode\u003eGMTDAuthorization\u003c/code\u003e protocol in Swift and Objective-C for iOS applications.\u003c/p\u003e\n"]]],[],null,["# Get authorization tokens\n\nWhat is a token?\n----------------\n\nFleet Engine requires the use of **JSON Web Tokens** (JWTs) for API method calls\nfrom **low-trust environments**: smartphones and browsers.\n\nA JWT originates on your server, is signed, encrypted, and passed to the client\nfor subsequent server interactions until it expires or is no longer valid.\n\n**Key details**\n\n- Use [Application Default Credentials](https://google.aip.dev/auth/4110) to authenticate and authorize against Fleet Engine.\n- Use an appropriate service account to sign JWTs. See [Fleet Engine serviceaccount](/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/service-accounts#fleet_engine_service_account_roles) roles in **Fleet Engine Basics**.\n\nFor more information about JSON Web Tokens, see [JSON Web Tokens](/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/jwt) in\n**Fleet Engine Essentials**.\n\nHow clients get tokens?\n-----------------------\n\nOnce a driver or consumer logs in to your app using the appropriate\nauthentication credentials, any updates issued from that device must use\nappropriate authorization tokens, which communicates to Fleet Engine the\npermissions for the app.\n\nAs the developer, your client implementation should provide the ability to\ndo the following:\n\n- Fetch a JSON Web Token from your server.\n- Reuse the token until it expires to minimize token refreshes.\n- Refresh the token when it expires.\n\nThe `GMTDAuthorization` protocol fetches JSON Web tokens at location update time\nbased on the `GMTD AuthorizationContext` object. The SDK\nmust package the tokens with the update information to send to Fleet Engine.\nMake sure that your server-side implementation can issue tokens before\ninitializing the SDK.\n\nFor details of the tokens expected by Fleet Engine, see\n[Issue JSON Web Tokens](/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/issue-jwt) for Fleet Engine.\n\nThe providerID is the same as the **Project ID** of your Google Cloud\nProject. For information on setting up the Google Cloud Project, see\n[Create your Fleet Engine project](/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/create-project).\n\nExample of an authentication token fetcher\n------------------------------------------\n\nThe following example shows an implementation of the `GMTDAuthorization`\nprotocol. \n\n### Swift\n\n import GoogleRidesharingDriver\n\n private let providerURL = \"INSERT_YOUR_TOKEN_PROVIDER_URL\"\n\n class SampleAccessTokenProvider: NSObject, GMTDAuthorization {\n private struct AuthToken {\n // The cached vehicle token.\n let token: String\n // Keep track of when the token expires for caching.\n let expiration: TimeInterval\n // Keep track of the vehicle ID the cached token is for.\n let vehicleID: String\n }\n\n enum AccessTokenError: Error {\n case missingAuthorizationContext\n case missingData\n }\n\n private var authToken: AuthToken?\n\n func fetchToken(\n with authorizationContext: GMTDAuthorizationContext?,\n completion: @escaping GMTDAuthTokenFetchCompletionHandler\n ) {\n // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.\n guard let authorizationContext = authorizationContext else {\n completion(nil, AccessTokenError.missingAuthorizationContext)\n return\n }\n let vehicleID = authorizationContext.vehicleID\n\n // If appropriate, use the cached token.\n if let authToken = authToken,\n authToken.expiration \u003e Date.now.timeIntervalSince1970 && authToken.vehicleID == vehicleID\n {\n completion(authToken.token, nil)\n return\n }\n\n // Otherwise, try to fetch a new token from your server.\n let request = URLRequest(url: URL(string: providerURL))\n let task = URLSession.shared.dataTask(with: request) { [weak self] data, _, error in\n guard let strongSelf = self else { return }\n guard error == nil else {\n completion(nil, error)\n return\n }\n\n // Replace the following key values with the appropriate keys based on your\n // server's expected response.\n let vehicleTokenKey = \"VEHICLE_TOKEN_KEY\"\n let tokenExpirationKey = \"TOKEN_EXPIRATION\"\n guard let data = data,\n let fetchData = try? JSONSerialization.jsonObject(with: data) as? [String: Any],\n let token = fetchData[vehicleTokenKey] as? String,\n let expiration = fetchData[tokenExpirationKey] as? Double\n else {\n completion(nil, AccessTokenError.missingData)\n return\n }\n\n strongSelf.authToken = AuthToken(\n token: token, expiration: expiration, vehicleID: vehicleID)\n completion(token, nil)\n }\n task.resume()\n }\n }\n\n### Objective-C\n\n #import \"SampleAccessTokenProvider.h\"\n #import \u003cGoogleRidesharingDriver/GoogleRidesharingDriver.h\u003e\n\n // SampleAccessTokenProvider.h\n @interface SampleAccessTokenProvider : NSObject\u003cGMTDAuthorization\u003e\n @end\n\n static NSString *const PROVIDER_URL = @\"INSERT_YOUR_TOKEN_PROVIDER_URL\";\n\n // SampleAccessTokenProvider.m\n @implementation SampleAccessTokenProvider{\n // The cached vehicle token.\n NSString *_cachedVehicleToken;\n // Keep track of the vehicle ID the cached token is for.\n NSString *_lastKnownVehicleID;\n // Keep track of when tokens expire for caching.\n NSTimeInterval _tokenExpiration;\n }\n\n - (void)fetchTokenWithContext:(nullable GMTDAuthorizationContext *)authorizationContext\n completion:(nonnull GMTDAuthTokenFetchCompletionHandler)completion {\n\n if (!completion) {\n NSAssert(NO, @\"%s encountered an unexpected nil completion.\", __PRETTY_FUNCTION__);\n return;\n }\n\n // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.\n NSString *vehicleID = authorizationContext.vehicleID;\n if (!vehicleID) {\n NSAssert(NO, @\"Vehicle ID is missing from authorizationContext.\");\n return;\n }\n\n // Clear cached vehicle token if vehicle ID has changed.\n if (![_lastKnownVehicleID isEqual:vehicleID]) {\n _tokenExpiration = 0.0;\n _cachedVehicleToken = nil;\n }\n _lastKnownVehicleID = vehicleID;\n\n // Clear cached vehicletoken if it has expired.\n if ([[NSDate date] timeIntervalSince1970] \u003e _tokenExpiration) {\n _cachedVehicleToken = nil;\n }\n\n // If appropriate, use the cached token.\n if (_cachedVehicleToken) {\n completion(_cachedVehicleToken, nil);\n return;\n }\n // Otherwise, try to fetch a new token from your server.\n NSURL *requestURL = [NSURL URLWithString:PROVIDER_URL];\n NSMutableURLRequest *request =\n [[NSMutableURLRequest alloc] initWithURL:requestURL];\n request.HTTPMethod = @\"GET\";\n // Replace the following key values with the appropriate keys based on your\n // server's expected response.\n NSString *vehicleTokenKey = @\"VEHICLE_TOKEN_KEY\";\n NSString *tokenExpirationKey = @\"TOKEN_EXPIRATION\";\n __weak typeof(self) weakSelf = self;\n void (^handler)(NSData *_Nullable data, NSURLResponse *_Nullable response,\n NSError *_Nullable error) =\n ^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {\n typeof(self) strongSelf = weakSelf;\n if (error) {\n completion(nil, error);\n return;\n }\n\n NSError *JSONError;\n NSMutableDictionary *JSONResponse =\n [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&JSONError];\n\n if (JSONError) {\n completion(nil, JSONError);\n return;\n } else {\n // Sample code only. No validation logic.\n id expirationData = JSONResponse[tokenExpirationKey];\n if ([expirationData isKindOfClass:[NSNumber class]]) {\n NSTimeInterval expirationTime = ((NSNumber *)expirationData).doubleValue;\n strongSelf-\u003e_tokenExpiration = [[NSDate date] timeIntervalSince1970] + expirationTime;\n }\n strongSelf-\u003e_cachedVehicleToken = JSONResponse[vehicleTokenKey];\n completion(JSONResponse[vehicleTokenKey], nil);\n }\n };\n NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];\n NSURLSession *mainQueueURLSession =\n [NSURLSession sessionWithConfiguration:config delegate:nil\n delegateQueue:[NSOperationQueue mainQueue]];\n NSURLSessionDataTask *task = [mainQueueURLSession dataTaskWithRequest:request completionHandler:handler];\n [task resume];\n }\n\n @end\n\nWhat's next\n-----------\n\n[Initialize the Driver SDK](/maps/documentation/mobility/driver-sdk/on-demand/ios/initialize-sdk)"]]