取得授權權杖

Consumer SDK 會使用 JSON Web Token 授權。JSON Web Token (JWT) 是授權權杖,可提供一或多項服務的聲明。

Consumer SDK 會使用應用程式提供的 JSON Web Token 與 Fleet Engine 通訊。如要瞭解 Fleet Engine 伺服器預期的權杖詳細資料,請參閱「JSON Web Token」和「核發 JSON Web Token」。

授權權杖可存取下列 Fleet Engine 服務:

  • TripService - 讓 Consumer SDK 存取行程詳細資料,包括車輛位置、路線和預計抵達時間。行程服務的授權權杖必須在權杖的 authorization 標頭中包含 tripid:TRIP_ID 聲明,其中 TRIP_ID 是要共用的隨選行程 ID。

  • VehicleService - 提供 Consumer SDK 概略車輛位置資訊,用於顯示車輛密度圖層和預估上車地點的預計抵達時間。由於 Consumer SDK 只會使用概略位置資訊,因此車輛服務的授權權杖不需要 vehicleid 聲明。

什麼是權杖?

低信任環境 (智慧型手機和瀏覽器) 呼叫 API 方法時,Fleet Engine 必須使用 JSON Web Token (JWT)。

JWT 會在伺服器上產生、簽署、加密,並傳遞至用戶端,以供後續伺服器互動使用,直到 JWT 過期或失效為止。

重要詳細資料

如要進一步瞭解 JSON Web Token,請參閱Fleet Engine 基礎知識中的「JSON Web Token」。

用戶如何取得權杖?

駕駛人或消費者使用適當的授權憑證登入應用程式後,從該裝置發出的任何更新都必須使用適當的授權權杖,向 Fleet Engine 傳達應用程式的權限。

身為開發人員,您的用戶端實作項目應提供下列功能:

  • 從伺服器擷取 JSON Web Token。
  • 在權杖過期前重複使用,盡量減少權杖重新整理次數。
  • 權杖到期時,請重新整理。

AuthTokenFactory 類別會在位置資訊更新時產生授權權杖。SDK 必須將權杖與更新資訊封裝在一起,然後傳送至 Fleet Engine。請先確認伺服器端實作項目可以發出權杖,再初始化 SDK。

如要瞭解 Fleet Engine 服務預期的權杖詳細資料,請參閱「為 Fleet Engine 簽發 JSON Web Token」。

授權權杖擷取器範例

以下程式碼範例說明如何實作授權權杖回呼。

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