取得授權權杖

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 宣告。

什麼是權杖?

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

JWT 源自伺服器,經過簽署和加密,並傳遞至用戶端,用於後續的伺服器互動,直到過期或失效為止。

重要詳細資料

如要進一步瞭解 JSON Web Token,請參閱「Fleet Engine 基本概念」中的「JSON Web Token」。

用戶端如何取得權杖?

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

開發人員應在用戶端實作中提供下列功能:

  • 從伺服器擷取 JSON Web Token。
  • 重複使用權杖,直到權杖到期,盡可能減少權杖更新次數。
  • 在權杖到期時更新。

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

如要進一步瞭解 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