Exploring Next.js 13: Enhancing Security with HTTP Cookie Authentication

I'm currently working on a web app using Next.js version 13.4.7. I am setting up authentication with JWT tokens from the backend (Laravel) and attempting to store them in http-only cookies.

Within a file named cookie.ts, which contains helper functions, there are two functions - one for setting the cookie after receiving it from the backend, and another for retrieving the cookie from the browser.

export const setAuthToken = (
    expiresIn: number,
    accessToken: string | null,
    baseUrl: string
) => {
    return fetch(`${baseUrl}/api/auth/login`, {
        method: "post",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({ expiresIn, accessToken }),
    });
};

export const getAccessTokenCookie = async (baseUrl: string) => {
    const response = await fetch(`${baseUrl}/api/auth/login`, {
        method: "get",
    });
    const data = await response.json();
    console.log(data, "data");

    return data.token;
};

The setAuthToken function sends a fetch request to /app/api/auth/login/route.ts.

import { cookies } from "next/headers";

export async function POST(request: Request) {
    const body = await request.json();
    const { expiresIn, accessToken } = body;
    cookies().set({
        name: "access_token",
        value: accessToken,
        httpOnly: true,
        secure: process.env.NODE_ENV !== "development",
        sameSite: "strict",
        maxAge: expiresIn,
        path: "/",
    });
}

export async function GET() {
    const accessToken = cookies().get("access_token");
    console.log(accessToken, "accessToken");

    if (!accessToken?.value) {
        return new Response(JSON.stringify({ token: null }), {
            headers: {
                "Content-Type": "application/json",
            },
        });
    }
    return new Response(JSON.stringify({ token: accessToken.value }), {
        headers: {
            "Content-Type": "application/json",
        },
    });
}

Although the POST request in setAuthToken successfully creates and stores the cookie, when attempting to retrieve it through getAccessTokenCookie, the cookie cannot be found, even within the GET function of the route.ts file.

Answer №1

This particular cookies instance is in a read-only state. If you want to update the cookies, you have to create a new Response object and include the Set-Cookie header.

For more information, you can visit this link.

Answer №2

Incorporate the given return statement into your post function:

return new Response(JSON.stringify({success:true}));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The useEffect function is executing two times

Check out this code snippet: import { type AppType } from 'next/app' import { api } from '~/utils/api' import '~/styles/globals.css' import Nav from '~/components/Nav' import { useEffect, useState } from 'react& ...

Guard against an array that contains different data types

I am trying to create a guard that ensures each entry in an array of loaders, which can be either query or proxy, is in the "success" state. Here is my attempted solution: type LoadedQueryResult = Extract<UseQueryResult, { status: 'success' }& ...

Leverage the power of React, Material-UI, and Typescript to inherit button props and incorporate a variety of unique

Looking to enhance the Material-UI button with additional variants like "square." How can I create a prop interface to merge/inherit props? Check out the following code snippet: import React from "react"; import { Button as MuiButton } from "@material-u ...

What is the best way to send two separate properties to the selector function?

My selector relies on another one, requiring the userId to function properly. Now, I want to enhance the selector to also accept a property named "userFriend". However, there seems to be an issue with passing this new parameter, as it only recognizes the ...

How can getStaticPaths be used to define routes?

Imagine you have these 3 route paths stored in an array: const routes = ["route1", "route2", "route3"]; To set up these paths, you would do the following: export async function getStaticPaths() { const routes = ["route1", "route2", "route3"]; const ...

invoking a method within an express route to retrieve and utilize middleware functions

For my project, I am working on a custom function to handle API request validation. Here is how it looks: export function validateBody(schema: string): (req: ExpressRequest, res: ExpressResponse, next: ExpressNextFunction) => void { return function ...

The current version of NPM - typescript is 2.2.2, and we are unable to update it to 2.4.1 due to it being a symlink

While attempting to install TypeScript through NPM, I encountered the error below. Can you help me identify the issue? Command: npm install typescript Error: The installation of TypeScript failed because it requires an update from version 2.2.2 to 2.4. ...

Seamless Navigation with Bootstrap Navbar and SmoothScroll

Currently, I have a custom-built navbar that functions perfectly, with full mobile responsiveness. However, I am facing an issue with the nav-item's (headings). The nav-item's direct users to different sections of the same page using #. I have i ...

A guide to efficiently pre-rendering secure APIs on a server for Next.js

Currently, I am working on a project that involves fetching data from multiple pages. However, the challenge lies in the fact that all APIs are secured, except for the initial API that fetches data for the home page. Furthermore, all other APIs are protect ...

Optimal technique for serializing variables containing Date objects in Next.js while preserving their data type

I am trying to create a table in Next.js using Tanstack Table with Prisma connected to a MySQL database. What is the most efficient way to handle Date objects stored in my database and pass them down for rendering in the table? I understand that I can ser ...

Utilizing string literals as index signatures

I've created a code snippet called MyTest that maps over an object: type MyTest<T> = { [P in keyof T]: T[P]; }; type Result = MyTest<{hello: 'world', foo: 2}>; // ^? type Result = { hello: 'world', foo: 2 } ...

Tips for retrieving a reactive variable from a setup() method?

I'm currently working on a small notes app and using Vue3 + Typescript to enhance my skills. The following code snippet demonstrates how to dynamically create and display an Array of notes: <template> <q-layout> <div v-for ...

Using either prop type for a React component in Typescript

Looking to build a Table component that can either render data from a prop or accept custom rendering via children. In order to achieve this, I need a type that can handle both scenarios with either data or children. I've come across some solutions a ...

Error: Trying to access the 'blogpost' property of an undefined variable results in a TypeError while executing the NPM RUN BUILD command in Next.js

Encountering a frustrating issue while trying to run my Next.js application for production build. The problem seems to be related to the "blogpost" parameter in the following codeblock: import React from "react"; import Slab from "../../comp ...

Guide to crafting a personalized parameter decorator for extracting the user from a request

Within my express.js application, I have set up an endpoint where I extract the user from the request as shown below: @Put('/:_id') async update (@Request() req: express.Request) { // @ts-ignore const user = req.user; .... } I am intereste ...

The error message ``TypeError [ERR_UNKNOWN_FILE_EXTENSION]:`` indicates a

I am encountering an error while trying to run the command ./bitgo-express --port 3080 --env test --bind localhost: (node:367854) ExperimentalWarning: The ESM module loader is experimental. internal/process/esm_loader.js:90 internalBinding('errors ...

Establishing a connection between TypeScript and MongoDB

Whenever I try to add the mongo connection to the request, I encounter an error. The error message says: 'Property 'dbClient' does not exist on type 'Request<ParamsDictionary>'. I want the connection to be accessible witho ...

Error encountered during compilation while attempting to import a JSON file in Angular 7

One great aspect of angular 7 is its compatibility with typescript 3.1: https://alligator.io/angular/angular-7/ I have made the following changes to the tsconfig.json file, within the 'compilerOptions' section: "resolveJsonModule": true, "esMo ...

Use an input of map<string,string> when passing to an angular component

Trying to pass an input value for a component reuse, but facing the challenge of having to use a "hardcoded" map of strings. Uncertain about how to effectively pass this information: <continue-p [additionalInfo]="{ "myString": "str ...

What is the best way to assign the result of a promise to a variable?

My code includes an async function that retrieves a value async fetchUserName(environment: string, itemName: string, authToken: string): Promise<any> { let result = await this.obtainDeviceName(environment, itemName, authToken); return ...