> ## Documentation Index
> Fetch the complete documentation index at: https://docs-unity.molca.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Session authentication

> Visitor OTP and member email/password login via ScenarioSessionManager.

**File:** `Assets/_MolcaSDK/_VR/Scripts/Scenario/Session/ScenarioSessionManager.cs`\
**Namespace:** `MolcaSDK.VR.Scenario.Session`\
**Type:** [RuntimeSubsystem](/core/runtime-subsystem)

Handles **visitor** and **member** login, stores **bearer token**, raises **`OnTokenReceived`**, loads content via **`GetContentAsync()`**, and drives session/scene flows (see full source for scene loading APIs).

## Visitor

**`VisitorLoginAsync(string playerCode)`** — Requires **exactly 6 characters**; builds **`VisitorLoginRequest`** with **`otp`** field, POSTs through [Scenario network config](/vr/scenario-network-config), then **`GetContentAsync()`** on success.

## Member

**`MemberLoginAsync(string email, string password)`** — Preferred member flow; validates non-empty strings, POSTs **`MemberLoginRequest`**, then loads content.

## Obsolete

**`MemberLoginAsyncUsingClerk(string clerkToken)`** — Marked **obsolete**; do not use for new work.

## Success path

Stores **bearer token**, invokes **`OnTokenReceived`**, **`SetStatus(AUTHENTICATED)`**, then **`GetContentAsync()`** which deserializes **`ContentResponse`**, applies **`ScenarioDataConfig.SetFetchedContent`**, and raises **`OnContentLoaded`**.

## Network

Endpoints and base **`HttpRequestAsset`** templates come from **`ScenarioNetworkConfig`** (e.g. YAML-backed); see [Scenario network config](/vr/scenario-network-config).

## Code

```csharp theme={null}
using Molca;
using MolcaSDK.VR.Scenario.Session;
using UnityEngine;

public class AuthBridge : MonoBehaviour
{
    private ScenarioSessionManager Session =>
        RuntimeManager.GetSubsystem<ScenarioSessionManager>();

    public async void LoginVisitor(string sixDigitCode)
    {
        bool ok = await Session.VisitorLoginAsync(sixDigitCode);
        if (!ok)
            Debug.LogWarning(Session.CurrentStatus.ToString());
    }

    public async void LoginMember(string email, string password)
    {
        bool ok = await Session.MemberLoginAsync(email, password);
        if (ok)
        {
            // Token already stored; content load ran inside MemberLoginAsync
        }
    }
}
```

Wire **`OnError`**, **`OnLoadingProgress`**, and **`OnContentLoaded`** in the Inspector for UI feedback without polling.

```csharp theme={null}
// Inspector or Awake:
session.OnError.AddListener(msg => Debug.LogError(msg));
```

## Troubleshooting

* **Visitor login always fails** — Input must be **length 6**; API errors surface on **`OnError`** (inspect **`response.errorMessage`** in logs).
* **`GetContentAsync` returns null / warning** — **`IsAuthenticated`** false (no token yet); ensure login completed successfully.
* **Member obsolete path** — Replace **`MemberLoginAsyncUsingClerk`** with **`MemberLoginAsync(email, password)`**.
* **Stuck in AUTHENTICATING** — Network failure or exception; check **`OnError`** and VPN/firewall to configured host.
* **Content empty** — Response JSON missing **`scenarios`** list; verify backend contract vs **`ContentResponse`** model.

## Related

* [Scenario network config](/vr/scenario-network-config)
* [Home UI](/vr/home-ui) — consumes **FetchedScenarios**
* [Auth UI](/shared/auth-ui) — shared widgets if used with VR
* [HttpClient](/core/http-client)
* [RuntimeManager](/core/runtime-manager)

## Unity Editor

<Frame hint="Auth VR scene — Canvas with login fields, or AuthUI component Inspector." caption="Auth scene or AuthUI wiring to ScenarioSessionManager">
  <img src="https://mintlify.s3.us-west-1.amazonaws.com/ptmolcateknologinusantara/images/features/vr/auth-vr-scene.png" alt="Unity Auth VR scene or Auth UI in Inspector" />
</Frame>
