how to store access token in http-only cookies with app router in next js 14 api

89 Views Asked by At

hi there im working on next js app and i've created login api. In that api im creating jwt token and i want to set this token to http-only cookies and send json response to user that logged in successfully here is my code...

import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken"; // Import jsonwebtoken library
import prismaClient from "../../../../../prisma/prismaClient";
import { NextResponse } from "next/server";
import vine, { errors } from "@vinejs/vine";
import { loginValidation } from "../../../../../vineValidation/validation";
import JSONAPIErrorReporter from "../../../../../vineValidation/errorReporter";

export async function POST(req, res) {
  const data = await req.json();
  const validator = vine.compile(loginValidation);
  validator.errorReporter = () => new JSONAPIErrorReporter();
  let user;
  try {
    await validator.validate(data);
    try {
      switch (data.role) {
        case "teacher":
          user = await prismaClient.Teacher.findUnique({
            where: { email: data.email, role: data.role },
          });
          break;
        case "admin":
          user = await prismaClient.Admin.findUnique({
            where: { email: data.email, role: data.role },
          });
          break;
        case "student":
          user = await prismaClient.Student.findUnique({
            where: { email: data.email, role: data.role },
          });
          break;
        default:
          return NextResponse.json({ error: "Invalid userType", status: 404 });
      }

      if (!user || !bcrypt.compareSync(data.password, user.hashedPassword)) {
        return NextResponse.json({
          error: "Incorrect Email Or Password",
          status: 404,
        });
      }
    } catch (error) {
      console.log(error.message);
      return NextResponse.json({
        error: "Database Connection Error",
        status: 500,
        msg: error.message,
      });
    }
  } catch (error) {
    if (error instanceof errors.E_VALIDATION_ERROR) {
      return NextResponse.json({
        error: "Validation error",
        errorMessage: error.messages,
        status: error.status,
      });
    } else {
      console.log(error.messages);
      return NextResponse.json({
        error: error.message,
        status: 500,
      });
    }
  }

  // Get the secret key from environment variable
  const secret = process.env.JWT_SECRET;

  // Create a token with the user data and the secret key
  const token = jwt.sign(user, secret);

  return NextResponse.json({
    message: "Logged In Successfully",
    status: 200,
    token,
  });
}
type here

i've tried this method too

export default async function handler(req, res) {
  // Your existing code for handling the POST request
  res.setHeader(
    "Set-Cookie",
    `accessToken=${token}; HttpOnly; Path=/; Max-Age=3600; SameSite=Strict`
  );

  return res.status(200).json({
    message: "Logged In Successfully",
    token, // Send the token back to the client as a response
  });
}

but i think in next 13/14 this method not working and got this error

⨯ Detected default export in 'D:\work space\pak millat\pak-millat\src\app\api\user\login\route.js'. Export a named export for each HTTP method instead.
 ⨯ TypeError: res.setHeader is not a function
    at POST (webpack-internal:///(rsc)/./src/app/api/user/login/route.js:88:9)
    at async D:\work space\pak millat\pak-millat\node_modules\next\dist\compiled\next-server\app-route.runtime.dev.js:6:63251
 ⨯ TypeError: res.setHeader is not a function
    at POST (webpack-internal:///(rsc)/./src/app/api/user/login/route.js:88:9)
    at async D:\work space\pak millat\pak-millat\node_modules\next\dist\compiled\next-server\app-route.runtime.dev.js:6:63251
0

There are 0 best solutions below