# How Stremio Web Handles User Authentication: A Technical Deep Dive

> Discover how Stremio Web manages user authentication. Learn about its message-passing architecture, credential validation, and global state updates for seamless UI.

- Repository: [Stremio/stremio-web](https://github.com/Stremio/stremio-web)
- Tags: deep-dive
- Published: 2026-05-23

---

**Stremio Web orchestrates authentication through a centralized message-passing architecture where UI components dispatch `Ctx.Authenticate` actions to the core layer, which validates credentials against Stremio's backend and updates the global profile state that React components subscribe to for instantaneous UI updates.**

The Stremio Web application handles user authentication by separating presentation logic from credential validation, using a context-driven state management system. This architecture enables multiple login methods (email, Facebook, Apple) while maintaining a single source of truth for authentication state across the React application.

## Authentication Architecture Overview

Stremio Web employs a three-layer authentication pipeline that decouples the UI from credential validation. The process begins in the **Intro** component, passes through the **Core** transport layer for validation, and propagates updates via the **Ctx** (context) model to subscribed React components.

According to the Stremio source code, the `Auth` object is defined in [`src/core/types/models/Ctx.d.ts`](https://github.com/Stremio/stremio-web/blob/main/src/core/types/models/Ctx.d.ts) as a TypeScript interface containing a unique key and user metadata. When authentication succeeds, the core emits a `Ctx` update containing this `Auth` object, which gets stored under `profile.auth` in the global state tree.

## The Login Flow: From UI to Core

### Initiating Authentication in Intro.js

When users initiate login from the **Intro** screen, the application dispatches a `Ctx.Authenticate` message through the core's transport layer. The [`src/routes/Intro/Intro.js`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Intro/Intro.js) file handles three distinct authentication methods through thin wrapper callbacks.

For **email and password authentication**, the component validates form input and dispatches:

```javascript
// src/routes/Intro/Intro.js – lines 39-60
core.transport.dispatch({
    action: 'Ctx',
    args: {
        action: 'Authenticate',
        args: {
            type: 'Login',
            email: state.email,
            password: state.password
        }
    }
});

```

**Facebook authentication** follows a similar pattern but includes a `facebook: true` flag after retrieving credentials via `useFacebookLogin`. The dispatch includes the Facebook-provided email and password with the additional flag to indicate the OAuth source.

**Apple authentication** dispatches with `type: 'Apple'` and includes the Apple token in the args object, allowing the core to verify the identity token against Apple's servers.

### Core Processing and Profile Updates

Once the Stremio core receives the `Ctx.Authenticate` message, it performs backend validation. For email/password combinations, it verifies credentials against Stremio's user database. For OAuth flows (Facebook, Apple), it validates the provided tokens with the respective identity providers.

Upon successful validation, the core constructs an `Auth` object according to the interface defined in [`src/core/types/models/Ctx.d.ts`](https://github.com/Stremio/stremio-web/blob/main/src/core/types/models/Ctx.d.ts):

```typescript
type Auth = {
    key: string;
    user: {
        _id: string;
        email: string;
        avatar?: string;
        // ... additional user metadata
    }
}

```

This object is then stored in the global context under `profile.auth`, triggering a state update that propagates through the React component tree via the `useCore` hook.

## React Components and Auth State

### Conditional Rendering Based on profile.auth

React components throughout the application subscribe to `profile.auth` to determine UI state. The authentication state drives conditional rendering in navigation, settings, and content areas.

In [`src/components/NavBar/HorizontalNavBar/NavMenu/NavMenuContent.js`](https://github.com/Stremio/stremio-web/blob/main/src/components/NavBar/HorizontalNavBar/NavMenu/NavMenuContent.js) (lines 63-77), the component checks `profile.auth` to decide between displaying the user's avatar or "Log In / Sign Up" buttons:

```javascript
// Conditional rendering pattern used in NavMenuContent.js
const NavUserSection = ({ profile }) => {
    if (profile.auth) {
        return <img src={profile.auth.user.avatar} alt={profile.auth.user.email} />;
    }
    return <button>Log In / Sign Up</button>;
};

```

The **Settings** route in [`src/routes/Settings/General/User/User.tsx`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Settings/General/User/User.tsx) (lines 16-48) displays the authenticated user's email and avatar, falling back to an "Anonymous user" label when `profile.auth` is `null`.

### Protected Routes Implementation

The application guards restricted routes using the `withProtectedRoutes` higher-order component located in [`src/App/withProtectedRoutes.js`](https://github.com/Stremio/stremio-web/blob/main/src/App/withProtectedRoutes.js) (lines 10-18). This wrapper checks `profile.auth` against `null` and redirects unauthenticated users to the Intro screen:

```javascript
// src/App/withProtectedRoutes.js – lines 10-18
const withProtectedRoutes = (Component) => (props) => {
    const { profile } = useCore();
    
    if (!profile.auth) {
        return <Redirect to="/intro" />;
    }
    return <Component {...props} />;
};

```

Because the profile state lives in the central `Ctx` store, authentication changes trigger immediate UI updates across all subscribed components without requiring manual refresh or prop drilling.

## Logout Mechanism

Logging out reverses the authentication flow through the same message-passing system. Components dispatch a `Ctx.Authenticate` action with `type: 'Logout'`, which instructs the core to clear the `Auth` object and set `profile.auth` back to `null`.

This state change immediately propagates to all subscribers, causing protected routes to redirect and navigation components to switch from the user avatar back to login prompts. The logout handler typically resides in the same navigation components that check `profile.auth`, ensuring consistent session management throughout the user interface.

## Summary

- **Message-based dispatch**: All authentication actions flow through `core.transport.dispatch()` with `action: 'Ctx'` and `args.action: 'Authenticate'`, creating a consistent interface for email, Facebook, and Apple logins.
- **Centralized state**: The `profile.auth` object in the global Ctx store serves as the single source of truth, containing the user's unique key and metadata when authenticated, or `null` when logged out.
- **Reactive UI updates**: React components use the `useCore` hook to subscribe to profile changes, enabling instantaneous UI transitions between authenticated and anonymous states.
- **Route protection**: The `withProtectedRoutes` HOC in [`src/App/withProtectedRoutes.js`](https://github.com/Stremio/stremio-web/blob/main/src/App/withProtectedRoutes.js) enforces authentication requirements by checking `profile.auth` and redirecting unauthorized users.
- **Type-safe definitions**: The `Auth` and `Profile` interfaces in [`src/core/types/models/Ctx.d.ts`](https://github.com/Stremio/stremio-web/blob/main/src/core/types/models/Ctx.d.ts) ensure consistent data structures across the TypeScript codebase.

## Frequently Asked Questions

### How does Stremio Web store authentication tokens?

Stremio Web stores the authentication token within the global context state managed by the core layer. The `Auth` object containing the user key and metadata is stored under `profile.auth` in the Ctx model, as defined in [`src/core/types/models/Ctx.d.ts`](https://github.com/Stremio/stremio-web/blob/main/src/core/types/models/Ctx.d.ts). React components access this state through the `useCore` hook rather than local storage or cookies, ensuring the token remains within the application's state management system.

### What authentication methods does Stremio Web support?

Stremio Web supports three authentication methods: traditional **email and password** login, **Facebook OAuth**, and **Apple Sign-In**. All methods dispatch the same `Ctx.Authenticate` message structure but vary in their `args` object. Email login sends `type: 'Login'` with credentials, Facebook includes `facebook: true`, and Apple specifies `type: 'Apple'` with the identity token.

### How does Stremio Web handle protected routes?

Protected routes are implemented using the `withProtectedRoutes` higher-order component in [`src/App/withProtectedRoutes.js`](https://github.com/Stremio/stremio-web/blob/main/src/App/withProtectedRoutes.js). This wrapper checks the `profile.auth` property from the global context state. If the value is `null` (indicating no active session), the component redirects the user to the Intro screen. If an `Auth` object exists, the requested route renders normally.

### Where is the user interface for authentication defined?

The primary authentication UI resides in [`src/routes/Intro/Intro.js`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Intro/Intro.js), which contains the login forms and OAuth initiation buttons. Navigation controls that reflect authentication state are located in [`src/components/NavBar/HorizontalNavBar/NavMenu/NavMenuContent.js`](https://github.com/Stremio/stremio-web/blob/main/src/components/NavBar/HorizontalNavBar/NavMenu/NavMenuContent.js), while user details and logout options appear in [`src/routes/Settings/General/User/User.tsx`](https://github.com/Stremio/stremio-web/blob/main/src/routes/Settings/General/User/User.tsx). These components collectively provide the complete authentication interface.