403 forbidden when calling custom controller from Nuxt

Hey guys, I’m getting a 403 Forbidden error when trying to access my custom strapi controller from my nuxt frontend.

I’ve used this to setup auth in strapi and nuxt: Auth with Strapi and Nuxt

I’m currently trying to retrieve the items specific to a authenticated user. To do this I created a custom route in Strapi (/api/routine/config/routes.json):

{
  "method": "GET",
  "path": "/routines/me",
  "handler": "Routine.me",
  "config": {
    "policies": []
  }
}

and a custom controller (/api/controllers/Routine.js):

module.exports = {
  me: async (ctx) => {
    const user = ctx.state.user;
    if (!user) {
      return ctx.badRequest(null, [{ messages: [{ id: 'No authorization header was found' }] }]);
    }

    const data = await strapi.services.routine.find({user:user.id});  

    if(!data){
      return ctx.notFound();
    }

    ctx.send(data);
  },
};

I already gave permission through Strapi admin for authenticated users to access ‘me’.

When I hit the endpoint from Nuxt:

async asyncData(context) {
    const authHeader = context.app.$auth.getToken('local')

    const routines = await axios.get(
        'http://localhost:1337/routines/me', {
            headers: { 'Authorization': authHeader }
        }
    )

    return { routines }
}

I get this error:

GET http://localhost:1337/routines/me 403 (Forbidden)

Why is the custom route returning forbidden? Am I doing something wrong with the strapi authorization configuration?

on the public or authorized role?

Hi, on the authorized role

Authorization token should start with Bearer:

headers: { 'Authorization': 'Bearer ' + authHeader }

You already check the authorization inside user-permissions plugin, there is no need to double check it inside your controller.

1 Like

Hi, I think const authHeader = context.app.$auth.getToken('local') already includes 'Bearer ', as when I log to console it prints: ‘Bearer XXXXXX’.

Still I tried changing it and then receive:

GET http://localhost:1337/routines/me 401 (Unauthorized)

A 403 is preferred over a 401 right?

Thanks for the quick reply!

@fooyonghan Sorry it seems your quick replies triggered our spam prevention, I have resolved the automated reports. Let me know if you have issues.

1 Like

Can you make a test from Postman? Set the authorization in it and try to get the /routines/me.

As I want to understand if something is wrong with the current axios request or with strapi configuration.

See the picture above for the postman request :point_up:

To me it seems to be my strapi configuration (see postman reply).

Not sure if it helps, but here are some screencaps of my admin:

I see that’s a new project, can you upload it to a public repo on GitHub? So we could make some tests.

Sure, I’ve put it here:

Repo removed as answer can be found in comment below

Here is the problem:

    {
      "method": "GET",
      "path": "/routines/:id",
      "handler": "routine.findOne",
      "config": {
        "policies": []
      }
    },
    {
      "method": "GET",
      "path": "/routines/me",
      "handler": "routine.me",
      "config": {
        "policies": []
      }

So basically you are hitting the first route right now and it assumes that
me is actually an :id. Koa is making the verifications with regex so in this case it takes the first matched route. Move the route with /me above that one with /:id

3 Likes

Wow thank you! What an amazing community :clap:

1 Like

You’re welcome :slight_smile: Problems are easier to find in code than in screenshots.

1 Like

Hello! I am using Strapi V4, and stuck with the same problem (created a post with detailed description here). I personally did not have findOne route specified in my /routes/custom.js file, but I wrote it down there below route which must be called. But still findOne is being called instead of custom route :frowning_face:

I’ve found the solution. Documentation says:

Routes files are loaded in alphabetical order. To load custom routes before core routes, make sure to name custom routes appropriately (e.g. 01-custom-routes.js and 02-core-routes.js ).

Previously I had this file structure:

/active-user
 /active-user/routes
  /active-user/routes/active-user.js
  /active-user/routes/custom.js

Changing it to the next file structure solved the issue:

/active-user
 /active-user/routes
  /active-user/routes/01-custom.js
  /active-user/routes/active-user.js