> For the complete documentation index, see [llms.txt](https://docs.baas.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.baas.sh/baas-sdk/authentication/sessions.md).

# Sessions

Read the current session, react to auth changes, refresh tokens, and sign out.

After a user signs in, the SDK holds a **session**. This guide covers reading it, reacting to changes, and ending it.

## Read the current session

`getSession()` resolves to the session, or `null` if signed out. It rejects when the session could not be restored or renewed; the codes are listed in [Error handling](/baas-sdk/resources/error-handling.md).

```ts
const session = await baas.auth.getSession();
if (session) {
  console.log('User:', session.address);
}
```

The session carries `address`, `accessToken`, `expiresAt` and `walletMode`; the type is in the [API reference](/baas-sdk/resources/api-reference.md#types). It is read-only. After a page reload, await `getSession()` before deciding whether the user is signed in. Browser cookie restrictions or a network failure can prevent restoration.

## React to changes

`onAuthStateChange()` fires `INITIAL_SESSION` once initial restoration has settled, then on every change (`SIGNED_IN`, `SIGNED_OUT`, `TOKEN_REFRESHED`). Use it to keep your UI in sync.

```ts
const unsubscribe = baas.auth.onAuthStateChange((event, session) => {
  if (session) {
    // user is signed in — update your UI or store
  } else {
    // user is signed out or session has expired — redirect to login
    // e.g. router.push('/login')
  }
});

// Later — stop listening
unsubscribe();
```

`onAuthStateChange` tracks the BaaS session, which the SDK also clears (`SIGNED_OUT`) when the signed-in external wallet switches accounts or disconnects. For external-wallet sign-ins, see [External wallet](/baas-sdk/authentication/external-wallet.md).

{% hint style="info" %}
**Sign-in and sign-out sync across tabs of the same site when the browser supports it.** Browser restrictions may prevent immediate updates.
{% endhint %}

## Sign out

```ts
await baas.auth.signOut();
```

`signOut()` signs the user out of this browser and notifies your `onAuthStateChange` listeners with `SIGNED_OUT`. If it fails, it throws `SIGNOUT_FAILED` and the session stays active: retry.

{% hint style="info" %}
**The passkey is preserved.** Signing out keeps the user's passkey on file and ends the session in this browser; other devices keep theirs.
{% endhint %}

## Session renewal

The SDK renews the session for you: the access token is refreshed automatically, and `TOKEN_REFRESHED` tells you when it did. Nothing to store or renew on your side.

Do not copy tokens to browser storage, analytics, or logs. Protect your app against XSS and limit third-party scripts.

## Sending the token to your own backend

`session.accessToken` is a standard JWT. If you have your own backend, you can forward it to identify the user.

```ts
const session = await baas.auth.getSession();
if (session) {
  await fetch('https://my-api.example.com/me', {
    headers: { Authorization: `Bearer ${session.accessToken}` },
  });
}
```

Your backend must verify the signature with the project’s trusted key and validate the expected issuer, audience, and expiration according to your API’s token contract. Decoding a JWT is not verification.

## Next

* [Use with React](/baas-sdk/integrations/react.md) — turn `onAuthStateChange` into a hook.
* [Manage user](/baas-sdk/manage-user.md) — update the signed-in user's email and push tokens.
* [Error handling](/baas-sdk/resources/error-handling.md) — handle expired sessions and refresh failures.
