Fetch post request returns 403 Forbidden



As the title stated, I keep receiving 403 Forbidden error when making fetch post request to adonis.js (localserver). All Loggers in the controller didn’t print to console. I’m not sure what else is missing.

I’m …

I’ve …

  • not changed any files except those stated below
  • cleared “adonis-session” cookie before reloading the page
  • cleared “XSRF-TOKEN” cookie before reloading the page
  • added “X-XSRF-TOKEN” to the request header after fresh page reload

frontend request object

"bodyUsed": true​
"cache": "default"​
"destination": ""​
"integrity": ""​
"mode": "cors"​
"redirect": "follow"​
"referrer": "about:client"​
"referrerPolicy": ""​
"signal": AbortSignal { aborted: false, onabort: null }​
"method": "POST"​
"credentials": "same-origin"​
"url": "http://localhost:3333/api/users/signup"
"headers": {
  "Accept": "application/json"
  "X-Requested-With": "Fetch"
  "Content-Type": "application/json"
  "X-XSRF-TOKEN": cookies.get("XSRF-TOKEN")
"body": {
  "username": "VALID_USERNAME"
  "email": "VALID_EMAIL"
  "password": "VALID_PASSWORD"
  "password_confirmation": "VALID_PASSWORD"

fronend response object

"bodyUsed": false
"ok": false
"redirected": false
"type": "basic"
"statusText": "Forbidden"
"status": 403
"url": "http://localhost:3333/api/users/signup"
"headers": {
  "access-control-allow-origin": "false"
  "connection": "keep-alive"
  "content-length": "1485"
  "content-type": "application/json; charset=utf-8"
  "date": "Wed, 08 May 2019 22:55:54 GMT"
  "x-content-type-options": "nosniff"
  "x-download-options": "noopen"
  "x-frame-options": "DENY"
  "x-xss-protection": "1; mode=block"
"body": ReadableStream { locked: false }



csrf: {
  enable: true,
  methods: [ "PATCH", "POST", "PUT", "DELETE" ],
  filterUris: [],
  cookieOptions: {
    httpOnly: false,
    sameSite: true,
    path: "/",
    maxAge: 7200,




authenticator: "session",

session: {
  serializer: "lucid",
  model: "App/Models/User",
  scheme: "session",
  uid: "username",
  password: "password",



"use strict"

const Helpers = use("Helpers")

Route.group(() => {

    .post("users/signup", "UsersController.signup")
    .middleware([ "guest" ])


/* NOTE: No route after this response */
Route.any("*", ({ response }) => response.download(Helpers.resourcesPath("static/index.html")))


"use strict"

const User = use("App/Models/User")
const Logger = use("Logger")
Logger.level = "debug"

class UsersController {
  async signup ({ auth, request, response }) {
    Logger.debug("signupRequest: %j", request.all())

    try {
      const user = await User
        .create(request.only([ "username", "email", "password" ]))

      await auth

        .plainCookie("isSignin", 1)
          success: true,
          data: null,
    catch (error) {
      Logger.debug("signup.catchError: %j", error)

        .plainCookie("isSignin", 0)
          success: false,
          errors: error,

module.exports = UsersController
1 Like


Hi, could you please also share the cors.js in Adonis config?
I think it was the issue about CORS.



@m1ng-s Thanks for helping me on this.


"use strict"

module.exports = {
  origin: false,
  methods: [ "GET", "PUT", "PATCH", "POST", "DELETE" ],
  headers: true,
  exposeHeaders: false,
  credentials: false,
  maxAge: 90,

I forgot to add that the website is served by adonis.js

"use strict"

const Helpers = use("Helpers")
/* NOTE: No route after this response */
Route.any("*", ({ response }) => response.download(Helpers.resourcesPath("static/index.html")))


Hi @LetsZiggy

I think your frontend framework is running on different domain/ports right?
If yes, you should change the origin in cors.js to allow access your API.
docs: https://adonisjs.com/docs/4.1/cors#_config

Hope its help :grinning:



Hi @m1ng-s, below were some of the steps I’ve tried but same 403 Forbidden

I’ve tried changing cors.js origin to …

  • true
    • default
  • http://localhost:3333
  • http://localhost
  • localhost:3333
  • localhost

I’ve also tried changing the request init data

  • mode: "cors"
    • default
  • credentials: "same-origin"
    • default
  • mode: "same-origin"
  • mode: "include"


The thing is, if I set shield.js csrf to false, the controller runs and the Loggers prints to terminal.
Even if I leave cors.js origin to false.



Yeah, coz CSRF and CORS are two different things all together. Now since you are building an API server, that renders views on the frontend and does all the communication via JSON API, there is no need of CSRF at all, simply disable it.



@m1ng-s @virk thanks for your help