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 過期或失效為止。
重要詳細資料
- 使用應用程式預設憑證向 Fleet Engine 進行驗證和授權。
- 使用適當的服務帳戶簽署 JWT。請參閱「Fleet Engine 基礎知識」一文中的「Fleet Engine 服務帳戶角色」。
如要進一步瞭解 JSON Web Token,請參閱《Fleet Engine 基礎知識》中的「JSON Web Token」。
用戶如何取得權杖?
駕駛人或消費者使用適當的授權憑證登入應用程式後,從該裝置發出的任何更新都必須使用適當的授權權杖,向 Fleet Engine 傳達應用程式的權限。
身為開發人員,您的用戶端實作項目應提供下列功能:
- 從伺服器擷取 JSON Web Token。
- 在權杖過期前重複使用,盡量減少權杖更新次數。
- 權杖到期時,請重新整理。
AuthTokenFactory 類別會在位置資訊更新時產生授權權杖。SDK 必須將權杖與更新資訊封裝在一起,然後傳送至 Fleet Engine。請先確認伺服器端實作項目可以發行權杖,再初始化 SDK。
如要瞭解 Fleet Engine 服務預期的權杖詳細資料,請參閱「為 Fleet Engine 簽發 JSON 網頁權杖」。
授權權杖擷取器範例
以下程式碼範例示範如何實作授權權杖回呼。
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
    }
  }
}