获取授权令牌

使用方 SDK 使用 JSON Web 令牌提供授权。JSON Web 令牌 (JWT) 是一种授权令牌,可针对某项服务提供一个或多个声明。

使用方 SDK 使用应用提供的 JSON Web 令牌 与 Fleet Engine 进行通信。如需详细了解 Fleet Engine 服务器,请参阅 JSON Web 令牌颁发 JSON Web 令牌

授权令牌提供对以下 Fleet Engine 服务的访问权限:

  • TripService - 向消费者 SDK 授予访问行程详情的权限,包括 车辆位置、路线和预计到达时间。行程服务的授权令牌 必须在令牌的 authorization 标头中添加 tripid:TRIP_ID 声明, 其中 TRIP_ID 是共享的按需行程的行程 ID。

  • VehicleService - 为使用方 SDK 提供 显示车辆密度图层时显示的车辆大致位置 估算上车点预计到达时间。由于消费者 SDK 仅使用近似值 车辆服务的授权令牌不需要 vehicleid 项版权主张。

什么是令牌?

Fleet Engine 要求使用 JSON Web 令牌 (JWT), 适当的服务账号,用于低信任度 API 方法调用 环境。低信任的环境包括智能手机和浏览器。JWT 源自您的服务器,这是一个完全可信的环境。JWT 经过签名和加密,并传递给客户端,以供后续服务器使用 直至过期或失效。

您的后端应使用 标准的应用默认凭据机制。制造商 请务必使用由相应服务账号签名的 JWT。对于 服务账号角色的列表,请参阅 Fleet Engine 服务账号角色 Fleet Engine 基础知识

如需详细了解 JSON 网络令牌,请参阅 JSON 网络令牌 Fleet Engine 基础知识

客户端如何获取令牌?

驾驶员或消费者使用相应的 授权凭据,那么从该设备发布的任何更新都必须使用 相应的授权令牌,用于向 Fleet Engine 传达 应用权限。

作为开发者,您的客户端实现应该能够 以下:

  • 从您的服务器提取 JSON 网络令牌。
  • 在令牌过期之前重复使用,以最大限度地减少令牌刷新。
  • 在令牌过期时刷新令牌。

AuthTokenFactory 类会在位置信息更新时生成授权令牌 。SDK 必须将令牌与更新打包在一起。 以便发送到 Fleet Engine。请确保您的服务器端 实施可以在初始化 SDK 之前颁发令牌。

如需详细了解 Fleet Engine 服务预期的令牌,请参阅问题 JSON 适用于 Fleet Engine 的 Web 令牌

授权令牌提取程序示例

以下代码示例演示了如何实现授权令牌 回调。

Java

class JsonAuthTokenFactory implements AuthTokenFactory {

  private static final String TOKEN_URL =
      "https://yourauthserver.example/token";

  private static class CachedToken {
    String tokenValue;
    long expiryTimeMs;
    String tripId;
  }

  private CachedToken token;

  /*

*   This method is called on a background thread. Blocking is OK. However, be
*   aware that no information can be obtained from Fleet Engine until this
*   method returns.
*/
@Override
public String getToken(AuthTokenContext context) {
  // If there is no existing token or token has expired, go get a new one.
  String tripId = context.getTripId();
  if (tripId == null) {
    throw new RuntimeException("Trip ID is missing from AuthTokenContext");
  }
  if (token == null || System.currentTimeMillis() > token.expiryTimeMs ||
      !tripId.equals(token.tripId)) {
    token = fetchNewToken(tripId);
  }
  return token.tokenValue;
}

  private static CachedToken fetchNewToken(String tripId) {
    String url = TOKEN_URL + "/" + tripId;
    CachedToken token = new CachedToken();

    try (Reader r = new InputStreamReader(new URL(url).openStream())) {
      com.google.gson.JsonObject obj
          = com.google.gson.JsonParser.parseReader(r).getAsJsonObject();

      token.tokenValue = obj.get("ServiceToken").getAsString();
      token.expiryTimeMs = obj.get("TokenExpiryMs").getAsLong();

      /*

    *   The expiry time could be an hour from now, but just to try and avoid
    *   passing expired tokens, we subtract 5 minutes from that time.
    */
    token.expiryTimeMs -= 5 * 60 * 1000;
  } catch (IOException e) {
    /*
    *   It's OK to throw exceptions here. The error listeners will receive the
    *   error thrown here.
    */
    throw new RuntimeException("Could not get auth token", e);
  }
  token.tripId = tripId;

    return token;
  }
}

Kotlin

class JsonAuthTokenFactory : AuthTokenFactory() {

  private var token: CachedToken? = null

  /*

*   This method is called on a background thread. Blocking is OK. However, be
*   aware that no information can be obtained from Fleet Engine until this
*   method returns.
*/
override fun getToken(context: AuthTokenContext): String {
  // If there is no existing token or token has expired, go get a new one.
  val tripId =
    context.getTripId() ?:
      throw RuntimeException("Trip ID is missing from AuthTokenContext")

    if (token == null || System.currentTimeMillis() > token.expiryTimeMs ||
        tripId != token.tripId) {
      token = fetchNewToken(tripId)
    }

    return token.tokenValue
  }

  class CachedToken(
    var tokenValue: String? = "",
    var expiryTimeMs: Long = 0,
    var tripId: String? = "",
  )

  private companion object {
    const val TOKEN_URL = "https://yourauthserver.example/token"

    fun fetchNewToken(tripId: String) {
      val url = "$TOKEN_URL/$tripId"
      val token = CachedToken()

      try {
        val reader = InputStreamReader(URL(url).openStream())

        reader.use {
          val obj = com.google.gson.JsonParser.parseReader(r).getAsJsonObject()

          token.tokenValue = obj.get("ServiceToken").getAsString()
          token.expiryTimeMs = obj.get("TokenExpiryMs").getAsLong()

          /*

        *   The expiry time could be an hour from now, but just to try and avoid
        *   passing expired tokens, we subtract 5 minutes from that time.
        */
        token.expiryTimeMs -= 5 * 60 * 1000
      }
    } catch (e: IOException) {
      /*
            *   It's OK to throw exceptions here. The error listeners will receive the
            *   error thrown here.
      */
      throw RuntimeException("Could not get auth token", e)
    }

      token.tripId = tripId

      return token
    }
  }
}

后续步骤

初始化使用方 SDK