WIX Headless with SDK

Question:
I’m experiencing an intermittent issue when using Wix Headless to obtain user refresh and access tokens during login. Sometimes I receive the tokens as expected, but other times the response is either rejected or remains pending. Has anyone else encountered this issue and found a solution?

Product:
Wix Headless (using the Wix SDK with OAuthStrategy)

What are you trying to achieve:
I’m aiming to implement a reliable login flow where, after a successful login, I can retrieve a session token and then obtain the corresponding access and refresh tokens for further authenticated actions. Consistency in receiving these tokens is critical for my application’s functionality.

What have you already tried:

  • Implemented the login function using client.auth.login to obtain a session token and client.auth.getMemberTokensForDirectLogin(sessionToken) to retrieve the tokens.
  • Reviewed documentation, forum topics, and related articles, but the intermittent nature of the issue (tokens sometimes being returned as a pending promise or resulting in errors) persists.
  • I’ve verified that the sessionToken is valid on every request made to getMemberTokensForDirectLogin(sessionToken). Despite the token being valid each time, I still encounter the same issue.

Additional information:
[Include any other pertinent details or information that might be helpful for people to know when trying to answer your question.]

Error Message:

POST https://www.wixapis.com/oauth2/token 400 (Bad Request)
Error logging in: Error: Failed to fetch tokens from OAuth API: . request id: null. Response: {"error":"unknown_error"}
    at async getMemberTokens 
    at async handleLogin 

Console Log:

Access and Refresh Tokens: Promise {<pending>}

Relevant Code:

  • HOOK :
import { OAuthStrategy, createClient } from "@wix/sdk";

const client = createClient({
  modules: {},
  auth: OAuthStrategy({
    clientId: process.env.NEXT_PUBLIC_WIX_CLIENT_ID!,
  }),
});

export let login = async ({ email, password }: { email: string; password: string; }) => {
  try {
    const response = await client.auth.login({ email, password });
  
    if (response) {
      const sessionToken: string = response.data.sessionToken;
      console.log("Session Token:", sessionToken);
      const tokens = client.auth.getMemberTokensForDirectLogin(sessionToken);
      console.log("Access and Refresh Tokens:", tokens);
      return tokens;
    }
  } catch (error) {
    console.error("Login API error:", error);
    throw error;
  }
};

And from the React component:

"use client";

import React, { useState } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Card,
  CardContent,
  CardDescription,
  CardFooter,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { AlertCircle, Loader2, ArrowLeft, Heart } from "lucide-react";
import { login } from "@/lib/createAuthClient";

export default function LoginPage() {
  const [email, setEmail] = useState("");
  const [sessionToken, setSessionToken] = useState("");
  const [password, setPassword] = useState("");
  const [message, setMessage] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const router = useRouter();

  const handleLogin = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsLoading(true);
    setMessage("");

    try {
      const tokens = await login({ email, password });
      console.log("Login successful. Tokens:", tokens);
      setMessage("Login successful!");
    } catch (error) {
      console.error("Error logging in:", error);
      setMessage(error.message || "Error logging in. Please try again.");
    } finally {
      setIsLoading(false);
    }
  };
}

Hello! I’m having trouble finding the direct link for headless customer care, but if you use this link and prompt the same as the image it will end up with the team that can assist here.

Althernatively, we have a dedicated headless channel in our Discord server where you can post this question to get some help from the headless dev community and team.

Headless Discord channel

Start a ticket

1 Like

Hi! I’ve run into similar intermittent issues with token retrieval using Wix Headless and the OAuthStrategy in the SDK, so you’re not alone. It can be frustrating when the tokens sometimes come through fine but other times get stuck in a pending state or fail outright. I haven’t found a definitive fix yet, but I can share a few things I’ve tried and some thoughts that might help you—or anyone else who’s tackled this—narrow it down.

From what you’ve described, it sounds like you’ve got the basics solid: using client.auth.login to get the session token and then client.auth.getMemberTokensForDirectLogin(sessionToken) to fetch the access and refresh tokens. Since you’ve confirmed the session token is valid each time, that rules out one common culprit. Here’s what I’ve explored in my own debugging that might be worth trying:

  1. Network or Timing Issues: I noticed that sometimes the pending promise or rejection could be tied to network latency or race conditions. Have you tried adding a small delay (e.g., using setTimeout) before calling getMemberTokensForDirectLogin? It’s a bit of a hack, but it helped me rule out timing problems between the login response and the token request.
  2. Error Handling and Logs: Wrapping the getMemberTokensForDirectLogin call in a try-catch block and logging the full error might reveal more. For me, the errors were sometimes vague (like a generic rejection), but occasionally I’d get a clue—like an expired session token or a server-side hiccup. Are you seeing anything specific in the rejected cases?
  3. Token Caching or State: I’ve wondered if the client’s internal token management might be getting tripped up. Have you tried explicitly setting the tokens with client.auth.setTokens() after fetching them, or clearing any cached tokens before the login flow? It’s possible the SDK is holding onto stale data intermittently.
  4. SDK Version: I’ve seen some quirks with older SDK versions. I’m currently on @wix/sdk@latest, but if you’re using an earlier one, updating might stabilize things. Alternatively, if you’re on the latest, rolling back to a previous stable version could be worth a shot.
  5. Wix Server Status: Since this is intermittent, it could be on Wix’s end—like a temporary glitch with their auth servers. I’ve checked their status page (https://status.wix.com/) during outages, and it’s occasionally lined up with my issues. Maybe keep an eye on that when you hit the problem?

For context, my setup is similar: I’m using a custom login flow with OAuthStrategy, aiming for a consistent token retrieval process. When it fails, I’ve seen the promise hang indefinitely or reject with no clear reason, even with a valid session token. One workaround I’ve toyed with is retrying the getMemberTokensForDirectLogin call (up to 2-3 attempts) with a short delay between retries—it’s not ideal, but it’s gotten me through in a pinch.

Have you checked the Wix Headless Discord or reached out to their support? I’ve found the community there pretty responsive, and they might have seen this before. I’d love to hear if you (or anyone else) have cracked this—I’m still chasing a reliable fix myself!

1 Like

Hello!
Thank you for your response, it was really constructive and contained numerous suggestions that can help.
I will try these suggestions, and we will keep in touch as soon as one of us finds a solution.
I actually tried the same approach by attempting 2–3 times with a short waiting period.
It improved the results, but it isn’t ideal to have this in the code; it’s not robust, even though it serves as an alternative until a solution is found.
For now, I think it is either a caching issue or a problem related to the SDK itself.
Otherwise, I also tried using client.auth.logout to invalidate the client’s existing tokens with set tokens, but that really didn’t improve the situation.
We will stay in contact until we find a solution!
thankyou

1 Like

Hello, thankyou very much i will try with the bot :raising_hands:t3: