How to extend auth controller in v4!?

Again, I’ve been wasting time for like 1 and a half weeks without any response or guide or documentation, I don’t understand why there isn’t any of this in v4? I saw this video, https://www.youtube.com/watch?v=OESLVW_lAQ8

First! The person just copies and pastes the auth.js, I do it in v4 and it asks me for many imports and folders that I don’t even know what to do!! I can’t even follow the tutorial.

Second, when I do this without extending a plugin Use of JWT in httpOnly cookie #4632 - #27 by davoscript when putting the middleware, I don’t know why, After testing my react app in chrome logging in against my backend in strapi and when I want to log in to the strapi administrator to use the content manager it won’t let me! I log in and it just keeps showing me the login, like there is some conflict and I don’t understand what.

Could someone please help me unblock this? I’m already frustrated enough, I just want to use the jwt on httpOnly cookies and get it from the back for authenticated requests. I have already posted on the forum, responded asking about this and no one answers me! Otherwise just tell me it’s impossible in strapi and I’ll do a cms turn.

This topic has been created from a Discord post (1217926863293517855) to give it more visibility.
It will be on Read-Only mode here.
Join the conversation on Discord

How to setup jwt in httpOnly cookies in v4!!!

Hi <@456291376661790720> sorry to hear about your frustration. Let me try to help.

in V4 we introduced a built-in API token feature for authentication, have you looked into it as an alternatie API tokens configuration | Strapi Documentation ?

<@1072591948499664996> How do I setup jwt in httpOnly cookies in v4?

Let me check the knowledge base for you. One moment! :books:


To set up JWT in httpOnly cookies in Strapi v4, you can follow these steps:

  1. Install the Nookies package in your frontend folder. Nookies is a third-party package that you can use to implement this functionality.
$ npm install nookies
  1. Update the pages/index.js file:
import { parseCookies, setCookie } from 'nookies'
export default function Home({posts}) {
 return (
 <div>
 <h1>Implementing Authenticated API Requests to Strapi</h1>
 {posts && posts.map((post) => (
 <div key={post.id}>
 <h3>{post.attributes.title}</h3>
 </div>
 ))}
 </div>

 )

}

export async function getServerSideProps(ctx) {
 const jwt = parseCookies(ctx).jwt

 // if there is a jwt token don’t authenticate the user again
 if (jwt) {
 // get posts from strapi REST API

 const res = await fetch(`<http://localhost:1337/api/posts`,> {
 headers: {
 Authorization: `Bearer ${jwt}`
 }
 });

 let posts = await res.json();
 posts = posts.data
 return {
 props: { 
 posts:posts 
 }
 }
}

 // if there isn’t a jwt token authenticate the user 

 const loginData = {
 identifier: '<User Email>',
 password: '<User Password>',
 }

 const login = await fetch(`<http://localhost:1337/api/auth/local`,> {
 method: "POST",
 headers: {
 'Accept': 'application/json',
 'Content-Type': 'application/json'
 },
 body: JSON.stringify(loginData)
 })

 const loginResponseData = await login.json();
 setCookie(ctx, 'jwt', loginResponseData.jwt, {
 maxAge: 30 * 24 * 60 * 60,
 path: '/'
 })

 // get posts from strapi REST API

 const res = await fetch(`<http://localhost:1337/api/posts`,> {
 headers: {
 Authorization: `Bearer ${loginResponseData.jwt}`
 }
 });
  1. In your Strapi backend, you can create a custom endpoint to set the JWT in a secure httpOnly cookie. Here’s an example of how you can do this:
const axios = require("axios");
module.exports = {
  async index(ctx) {
    const { body } = ctx.request;
    const hostname = "localhost";
    const absoluteURL = `<http://${hostname}:${strapi.config.server.port}`;>
    const sanitizeOutput = (user) => {
      const {
        password,
        resetPasswordToken,
        confirmationToken,
        ...sanitizedUser
      } = user;
      return sanitizedUser;
    };
    try {
      let { data } = await axios.post(`${absoluteURL}/api/auth/local`, body);
      const populatedUser = await strapi.entityService.findOne(
        "plugin::users-permissions.user",
        data.user.id,
        {
          populate: {
            role: {
              fields: ["type"],
            },
          },
        }
      );
      data.user = sanitizeOutput(populatedUser);
      if (data && data.jwt) {
        ctx.cookies.set("jwt", data.jwt, {
          httpOnly: true,
          secure: false,
          maxAge: 1000 * 60 * 60 * 24 * 14, // 14 Day Age
        });
      }
    } catch (error) {
      // handle error
    }
  },
};

Please note that this is a basic example and you might need to adjust it according to your needs.

Sources:


Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

<@713148383342100552> I think that doesn’t help me too much, first of all I want to say that I already have a custom route set, where from my backend I make a request to my own backend to /auth/local if it’s a 200 the cookie is set.

The problem is how to obtain that cookie, i use a global middleware that takes the jwt of the cookie and sets it in the headers, but sets a Bearer token in each route even if it is not authenticated and when sending an authorization header to a public route this returns a 403, for example every time I reload the strapi admin home page it triggers the middleware for anything. I solved this by excluding urls that start with /admin /content-manager etc but it is a very “manual” fix and I honestly don’t like it very much!! I don’t see that there is an official way to implement this. And I don’t know if there is any way to implement my middleware at a lower level and not globally. The issue is that if I set the middleware at the api level, I have to put my middleware file in all the collections I have from my api?? From what I understand I can’t call 1 single middleware file from different api collections

<@713148383342100552> My project is about an online business manager (web) for small and medium-sized companies, that is, they can add their products, register their orders, have customer data and perhaps some payment gateway in the future, so, i should have jwt in localStorage or go for something else like httpOnly Cookies? with this information that I give you about my project?

<@456291376661790720> Did you join open office hours so they can help you troubleshoot live ?

<@456291376661790720> there are some strapi tutorials which are very helpfulp for this. I found one using NextAuth and that is the one I suse, obviously I am using NextJS for my FE

<@456291376661790720> yes, it would depend on what frontend you are using. I am using next js 14 you can see this example where I am setting httpOnly cookie. music-player-next-strapi/frontend/src/data/actions/auth-actions.ts at main · PaulBratslavsky/music-player-next-strapi · GitHub