获取授权令牌

使用 JSON Web 令牌提供授权。JSON Web 令牌 (JWT) 是一种授权令牌,用于提供对服务的一个或多个声明。

使用户 SDK 使用应用提供的 JSON Web 令牌与车队引擎进行通信。如需详细了解车队引擎服务器预期的令牌,请参阅 JSON Web 令牌签发 JSON Web 令牌

授权令牌可访问以下车队引擎服务:

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

  • VehicleService - 向 Consumer SDK 提供有关大致车辆位置的信息,以显示车辆密度图层并估算接人点预计到达时间。由于 Consumer SDK 仅使用大致位置信息,因此车辆服务的授权令牌不需要 vehicleid 声明。

什么是令牌?

Fleet Engine 要求从低信任环境(智能手机和浏览器)进行 API 方法调用时,使用 JSON Web 令牌 (JWT)。

JWT 起源于您的服务器,经过签名和加密后传递给客户端,以便在到期或失效之前进行后续服务器互动。

关键详情

如需详细了解 JSON Web 令牌,请参阅车队引擎必备知识中的 JSON Web 令牌

客户如何获取令牌?

当驾驶员或使用方使用适当的授权凭据登录您的应用后,从该设备发出的任何更新都必须使用适当的授权令牌,这些令牌会将应用的权限传达给车队引擎。

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

  • 从您的服务器提取 JSON Web 令牌。
  • 在令牌过期之前重复使用该令牌,以尽可能减少令牌刷新次数。
  • 在令牌过期时刷新令牌。

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

如需详细了解 Fleet Engine 服务所需的令牌,请参阅 Fleet Engine 的签发 JSON 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