Case Study

Cookie-Based Authentication in React Native with NextAuth.js

Last Updated

While developing the cross-platform application, Sunshine Digital Solutions experienced yet another one of those moments that will always be annoying: figuring out the flow of a session-based, secure authentication, and how to implement it in a React Native application, while using an existing backend built from Next.js and NextAuth.js.

 

Most developers turn to JWT-based setups or OAuth in-app flows using WebViews or expo-auth-session, but there’s a cleaner, more secure way.

 

nextauth-js

 

This case study breaks down how our team implemented a production-grade “NextAuth React Native” authentication flow using Axios and @react-native-cookies/ cookies, without changing any backend logic or using JWTs.

 

This approach:

 
  • Utilizes httpOnly cookies to ensure session security.
  • Requires no changes to your Next.js backend or API routes.
  • Comes ready to use on Expo, dev clients, or any React Native configuration.
  • Maintains session state on application reloads and removes it properly on logout.

What Tools & Libraries Did We Use?

After deep experimentation and research, our developer implemented a clean, production-ready cookie-based authentication system in React Native using:

 
Stack Element Purpose
NextAuth.js Handles sessions on the Next.js API side
Axios HTTP client for React Native
@react-native-cookies/cookies Native cookie handling
expo-secure-store Secure local storage of user data (optional)
 

And best of all, without touching a single line of backend logic.

 

What Steps Did We Follow to Implement NextAuth React Native Integration?

We assume you’re using the default NextAuth.js credential provider setup on your backend:

Backend Setup


// pages/api/auth/[...nextauth].ts
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

export default NextAuth({
  providers: [
    CredentialsProvider({
      authorize: async (credentials) => {
        // your login logic
      }
    })
  ],
  session: {
    strategy: "database", // or "jwt" — both work
  },
  callbacks: {
    async session({ session, user }) {
      return session;
    },
  },
  // Additional options as needed...
});

Step 1: Axios API Wrapper with Cookie Support


// services/api.ts
import axios from "axios";
import CookieManager from "@react-native-cookies/cookies";
import { API_BASE_URL } from "../constants";

const api = axios.create({
  baseURL: API_BASE_URL,
  withCredentials: true,
  headers: { "Content-Type": "application/json" },
});

api.interceptors.request.use(async (config) => {
  const cookies = await CookieManager.get(API_BASE_URL);
  const cookieHeader = Object.entries(cookies)
    .map(([name, cookie]) => `${name}=${cookie.value}`)
    .join("; ");
  if (cookieHeader) {
    config.headers.Cookie = cookieHeader;
  }
  return config;
});

Step 2: Login Using NextAuth’s Credential Provider


// services/api.ts (continued)

async function fetchCsrfToken() {
  const res = await api.get("/api/auth/csrf");
  return res.data.csrfToken;
}

export async function login(email: string, password: string) {
  const csrfToken = await fetchCsrfToken();
  const body = new URLSearchParams({
    csrfToken,
    email,
    password,
    callbackUrl: "",
    json: "true",
  }).toString();

  const signInRes = await api.post("/api/auth/callback/credentials", body, {
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
  });

  if (!signInRes.data || signInRes.data.error) {
    throw new Error(signInRes.data.error || "Login failed");
  }

  const sessionRes = await api.get("/api/auth/session");
  return sessionRes.data.user;
}

Step 3: Logout (Including Cookie Clearing)


// services/api.ts
export async function logout() {
  await api.post("/api/auth/signout?redirect=false");
}

// In auth-provider.tsx
await CookieManager.clearAll(); // This ensures session cookie is gone on app restart

Step 4: AuthProvider for Session Persistence


// context/auth-provider.tsx
useEffect(() => {
  const loadSession = async () => {
    try {
      const res = await fetch(`${API_BASE_URL}/api/auth/session`, {
        method: "GET",
        credentials: "include",
      });
      if (res.ok) {
        const data = await res.json();
        setUser(data.user);
      }
    } catch (e) {
      setUser(null);
    } finally {
      setIsLoading(false);
    }
  };
  loadSession();
}, []);

Bonus Step: Save Profile Securely (Optional)


import * as SecureStore from "expo-secure-store";

export async function saveUserData(userData: any) {
  await SecureStore.setItemAsync("USER_DATA", JSON.stringify(userData));
}

export async function getUserData() {
  const raw = await SecureStore.getItemAsync("USER_DATA");
  return raw ? JSON.parse(raw) : null;
}
 

Why Was This Approach Better Than JWT or WebViews?

Instead of relying on complex token handling or clunky WebView-based flows, our approach offered a cleaner and more secure path. Here’s why it proved to be the better choice:

 

advantages-of-nextauth-js

 
  • No JWTs: We avoided the pitfalls of manually managing tokens and refreshing logic.
  • HttpOnly Cookie Sessions: Fully secure, server-controlled sessions just like in browsers.
  • Truly Native: No reliance on WebViews or third-party OAuth hacks.
  • Works with Expo or any RN Setup: No bare workflow or ejected app needed, this NextAuth React Native setup works.

Why Sunshine Digital Solutions Is Your Ideal Partner?

Sunshine Digital Solutions not only meets technical problems, but we also build systems that grow with the customer. As an example of our elite technical skills with real-world challenges, we used cookie-based authentication flows.

 

When we take up a project, we provide:

Proof of Expertise → We avoid backend systems and productivity wastes by implementing production-ready authentication systems.

Ready for the Future → Developer centric implementations which are secure, scalable and save time as well as lowers the risk.

Partnership Throughout → We simplify the complexity of your applications by collaborating with you on design and deployment. This way, your applications will function flawlessly on multiple devices.

 

If your aim is to have secure and yet high performing mobile or web applications, Sunshine Digital Solutions is the right partner for you. We are experts at helping you sidestep the most common and painful challenges faced during Von Exchange and offer outcome-based solutions you can deploy in real time.