Tokens & Authentication

Authentication

Stream uses JWT (JSON Web Tokens) to authenticate users so they can open WebSocket connections and send API requests. When a user opens your app, they first pass through your own authentication system. After that, the Stream SDK is initialized and a client instance is created. The device then requests a Stream token from your server. Your server verifies the request and returns a valid token. Once the device receives this token, the user is authenticated and ready to start using chat.

Tokens are signed with your API secret, so they are always created on your server. A client SDK is initialized with the API key alone and cannot mint a token. A token intended for client use must include the user_id claim in its payload.

For the server-side methods that create tokens, set expiry, and revoke tokens, see Tokens & Authentication in the server docs.

Token Providers

A concept we will refer to throughout the docs is a Token Provider. At a high level, the Token Provider is an endpoint on your server that can perform the following sequence of tasks:

  1. Receive information about a user from the front end.

  2. Validate that user information against your system.

  3. Provide a User-ID corresponding to that user to the server client's token creation method.

  4. Return that token to the front end.

Your endpoint must authenticate the caller before it issues a token. An endpoint that returns a token for any user ID it is given lets any caller impersonate any user.

Each SDK accepts either a token string or a token provider when you connect. For the provider signature in your language, see Connecting Users.

Token Expiration and Refresh

By default, user tokens are valid indefinitely. Your server can issue tokens with an expiry instead, which is the recommended setup for production, since a leaked token then stops working on its own.

Expiry only works if you connect with a token provider rather than a token string. The SDK calls your provider again when it needs a fresh token, which covers token expiry, an authentication error, and a reconnection that cannot reuse the cached token. If you passed a static string, the SDK has nothing to call and the connection fails once that token expires.

Keep your provider implementation resilient to a missing or slow network, because it runs on reconnection as well as on first connect.

On Android, the SDK manages the WebSocket connection across the app lifecycle and calls your TokenProvider again when a fresh token is needed. For the full lifecycle behavior, manual disconnect and reconnect, and how to handle token fetch failures in the background, see Handling User Connection.

Authentication Errors

Authentication failures come back as HTTP 401 with a Stream error code that tells you which part of the token was rejected.

Stream CodeNameMeaning
5Authentication ErrorUnauthenticated, problem with authentication
40Authentication Token ExpiredThe token's expiry has passed
41Authentication Token Not Valid YetThe token is not valid yet
42Authentication Token Before Issued AtThe token date is incorrect
43Authentication Token Signature InvalidThe token was not signed with your API secret
2Access Key ErrorThe API key the client was initialized with is invalid

A 40 means your server issued a token that has since expired, so the fix is a token provider rather than a static token. A 43 usually means the token was signed with the secret from a different app. The full error list is on the API Errors & Response page.

Developer Tokens

For development applications, it is possible to disable token authentication and use client-side generated tokens or a manually generated static token. Disabling auth checks is not suitable for a production application and should only be done for proofs-of-concept and applications in the early development stage. To enable development tokens, you need to change your application configuration.

On the Dashboard:

  1. Select the App you want to enable developer tokens on and ensure it is in Development mode

  2. Click App name to enter the Chat Overview

  3. Scroll to the General section

  4. Toggle Disable Authentication Checks

This disables the authentication check, but does not remove the requirement to send a token. Send either a client generated development token, or manually create one and hard code it into your application.

await client.connectUser(
  {
    id: "john",
    name: "John Doe",
    image: "https://getstream.io/random_svg/?name=John",
  },
  client.devToken("john"),
);

Manually Generating Tokens

You can use the JWT generator on this page to generate a User Token JWT without needing to set up a server client. You can use this token for prototyping and debugging; usually by hardcoding this into your application or passing it as an environment value at initialization.

You will need the following values to generate a token:

  • User ID : A unique string to identify a user.

  • API Secret : You can find this value in the Dashboard.

To generate a token, provide a User ID and your API Secret to the following generator:

For more information on how JWT works, please visit https://jwt.io.