获取授权令牌

Consumer SDK 使用 JSON 网络令牌提供授权。JSON Web 令牌 (JWT) 是一种授权令牌,可提供一项或多项服务声明。

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

授权令牌可用于访问以下 Fleet Engine 服务:

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

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

什么是令牌?

对于来自低信任环境(智能手机和浏览器)的 API 方法调用,Fleet Engine 要求使用 JSON Web 令牌 (JWT)。

JWT 源自您的服务器,经过签名和加密后传递给客户端,以供后续服务器交互使用,直到过期或不再有效。

关键详细信息

如需详细了解 JSON Web 令牌,请参阅 Fleet Engine 基础知识中的 JSON Web 令牌

客户如何获取令牌?

司机或消费者使用相应的授权凭据登录您的应用后,从该设备发出的任何更新都必须使用相应的授权令牌,以便向 Fleet Engine 传达应用的权限。

作为开发者,您的客户端实现应提供以下功能:

  • 从服务器获取 JSON Web 令牌。
  • 重复使用令牌,直到其过期,以尽可能减少令牌刷新次数。
  • 在令牌过期时刷新令牌。

AuthTokenFactory 类会在位置信息更新时生成授权令牌。SDK 必须将令牌与更新信息一起打包,然后发送到 Fleet Engine。在初始化 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
    }
  }
}

后续步骤

初始化 Consumer SDK