認証トークンを取得する

Consumer SDK は、JSON Web Token を使用して認証を行います。JSON Web Token (JWT)は、サービスに対して 1 つ以上のクレームを提供する認証トークンです。

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 を使用してください。1 つの サービス アカウントのロールのリストについては、Fleet Engine サービス アカウントのロールをご覧ください。 「Fleet Engine Basics」をご覧ください。

一方、バックエンドは、標準のアプリケーションのデフォルト認証情報メカニズムを使用して、Fleet Engine に対して認証と承認を行う必要があります。

JSON Web Token の詳細については、JSON Web Token をご覧ください。 Fleet Engine Essentials

クライアントはトークンをどのように取得しますか?

ドライバまたはコンシューマが適切な API を使用してアプリにログインしたら、 そのデバイスから発行されるアップデートには、 適切な認可トークンが Fleet Engine と通信し、 付与します。

デベロッパーは、クライアントの実装で次の機能を提供する必要があります。 次のとおりです。

  • サーバーから JSON ウェブトークンを取得します。
  • 有効期限が切れるまでトークンを再利用して、トークンの更新を最小限にします。
  • 期限切れになったらトークンを更新します。

AuthTokenFactory クラスが位置情報の更新時に認証トークンを生成する あります。SDK は更新とともにトークンをパッケージ化する必要がある Fleet Engine に送信しますサーバーサイドの SDK を初期化する前にトークンを発行できます。

Fleet Engine サービスによって要求されるトークンの詳細については、Issue JSON をご覧ください。 Fleet Engine 用のウェブトークン

認証トークン フェッチャーの例

次のコードサンプルは、認証トークンを実装する方法を示しています。 呼び出すことができます。

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 を初期化する