Skip to content

Authentication

BioTime SDK authenticates against the device's /api-token-auth/ endpoint and manages the resulting token for you, via BioTime\Auth\TokenManager.

How it works

Your code calls a resource method


BioTime\Client


TokenManager::getToken()

   ┌────┴─────┐
   │ Cached?  │
   └────┬─────┘
   Yes  │  No
   ┌────┘  └──────────────┐
   ▼                       ▼
Use cached token     POST /api-token-auth/
   │                  (username + password)
   │                       │
   │                       ▼
   │                 Cache the token
   │                       │
   └───────────┬───────────┘

    Send the actual API request

       ┌───────┴────────┐
   200/2xx            401 Unauthorized
       │                   │
       ▼                   ▼
   Return result   Forget cached token, force
                    re-authenticate, retry once

                    ┌──────┴──────┐
                 Success        Still fails
                    │                │
                    ▼                ▼
              Return result   Throw ApiException

Token acquisition

TokenManager::authenticate() sends the configured username/password as form parameters to POST /api-token-auth/. The device is expected to respond with a JSON body containing a token field. If the request fails, returns a non-2xx status, or the response has no token, an AuthenticationException is thrown.

Token caching

Where the token is stored depends on whether a PSR-16 cache was provided in Config:

  • With a cache (Config::$cache set) — the token is written via $cache->set($tokenCacheKey, $token, $tokenTtlSeconds), so it survives across requests/processes if your cache backend does (e.g. Redis, Memcached, a database-backed cache, or Laravel's cache store).
  • Without a cache — the token is kept in an in-memory static array (TokenManager::$memoryStore) that only lives for the current PHP process. This means a plain PHP script or a single job run reuses the token across multiple calls within that run, but a fresh HTTP request in a typical web app starts with no cached token unless you configure a real cache.

See Caching for how to plug in a PSR-16 cache, and Laravel integration for how the framework's cache store is wired up automatically.

Token expiration

The device's own token lifetime is not queried by the SDK — instead, tokenTtlSeconds (default 43200, i.e. 12 hours, matching the device's own default) controls how long the SDK's cache entry is considered valid. When the cache entry expires, the next call re-authenticates.

Automatic re-authentication on 401

Every authenticated request goes through Client::authenticatedRequest(), which:

  1. Sends the request with the current token.
  2. If the response is 401 Unauthorized, it forgets the cached token, forces a fresh getToken(forceRefresh: true) call, and retries the request once with the new token.
  3. If the retry also fails, the failure (including a 401 again) is surfaced as an ApiException/AuthenticationException like any other failed request.

This means an expired token is transparent to your application code in the common case — you don't need to catch a 401 and manually retry yourself.

What you don't need to do

You never call TokenManager directly, and you never attach the Authorization header yourself — every resource method goes through Client, which does this for every request. You only need to supply username/password via Configuration.

Distributed under the MIT License.