## What is a token?

Fleet Engine requires the use of **JSON Web Tokens** (JWTs) for API method calls
from **low-trust environments**: smartphones and browsers.

A JWT originates on your server, is signed, encrypted, and passed to the client
for subsequent server interactions until it expires or is no longer valid.

**Key details**

- Use [Application Default Credentials](https://google.aip.dev/auth/4110) to authenticate and authorize against Fleet Engine.
- Use an appropriate service account to sign JWTs. See [Fleet Engine serviceaccount](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/service-accounts.md.txt#fleet_engine_service_account_roles) roles in **Fleet Engine Basics**.

For more information about JSON Web Tokens, see [JSON Web Tokens](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/jwt.md.txt) in
**Fleet Engine Essentials**.

## How do clients get tokens?

Once a driver or consumer logs in to your app using the appropriate
authorization credentials, any updates issued from that device must use
appropriate authorization tokens, which communicates to Fleet Engine the
permissions for the app.

As the developer, your client implementation should provide the ability to do
the following:

- Fetch a JSON Web Token from your server.
- Reuse the token until it expires to minimize token refreshes.
- Refresh the token when it expires.

The `AuthTokenFactory` class generates authorization tokens at location update
time. The SDK must package the tokens with the update
information to send to Fleet Engine. Make sure that your server-side
implementation can issue tokens before initializing the SDK.

For details of the tokens expected by the Fleet Engine service, see [Issue JSON
Web Tokens](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/issue-jwt) for Fleet Engine.

## Example of an authorization token fetcher

Here is a skeleton implementation of an `AuthTokenFactory`:

```java
class JsonAuthTokenFactory implements AuthTokenFactory {
  private String vehicleServiceToken;  // initially null
  private long expiryTimeMs = 0;
  private String vehicleId;

  // This method is called on a thread whose only responsibility is to send
  // location updates. Blocking is OK, but just know that no location updates
  // can occur until this method returns.
  @Override
  public String getToken(AuthTokenContext authTokenContext) {
    String vehicleId = requireNonNull(context.getVehicleId());

    if (System.currentTimeMillis() > expiryTimeMs || !vehicleId.equals(this.vehicleId)) {
      // The token has expired, go get a new one.
      fetchNewToken(vehicleId);
    }

    return vehicleServiceToken;
  }

  private void fetchNewToken(String vehicleId) {
    String url = "https://yourauthserver.example/token/" + vehicleId;

    try (Reader r = new InputStreamReader(new URL(url).openStream())) {
      com.google.gson.JsonObject obj
          = com.google.gson.JsonParser.parseReader(r).getAsJsonObject();
      vehicleServiceToken = obj.get("VehicleServiceToken").getAsString();
      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 10 minutes from that time.
      expiryTimeMs -= 10 * 60 * 1000;
      this.vehicleId = vehicleId;
    } catch (IOException e) {
      // It's OK to throw exceptions here. The StatusListener you passed to
      // create the DriverContext class will be notified and passed along the failed
      // update warning.
      throw new RuntimeException("Could not get auth token", e);
    }
  }
}
```

This particular implementation uses the built-in Java HTTP client to fetch a
token in JSON format from the authorization server. The client saves the token
for reuse and re-fetches the token if the old token is within 10 minutes of its
expiry time.

Your implementation may do things differently, such as using a background thread
to refresh tokens.

For the available client libraries for Fleet Engine, see
[Client libraries for scheduled tasks services](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/client-libraries-tasks.md.txt).

## What's next

[Initialize the Driver SDK](https://developers.google.com/maps/documentation/mobility/driver-sdk/scheduled/android/initialize-sdk.md.txt)