0

i'm trying to create login form with nuxtjs as front end and slim php as backend api, when i tried to access the API, i see the request method that i send is OPTIONS not POST, and in chrome dev console error shown that the request is blocked (CORS). I know i have to set Access-Control-Allow-Methods add OPTIONS into it, but still failed, where to set that in nuxt js(nuxt.config) or slim php?

I have tried to access the api from postman and it work's just fine, i can see Access-Control-Allow-Methods headers has OPTIONS in it, but still it failed when i tried in vue apps

commons.app.js:434 OPTIONS http://localhost:8080/login 401 (Unauthorized)

Access to XMLHttpRequest at 'http://localhost:8080/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Code from slim php (API)

routes.php

// login routes
$app->post('/login', function (Request $request, Response $response, array $args) {

        $input = $request->getParsedBody();
        $sql = "SELECT * FROM groups
                LEFT JOIN users_groups ON groups.groups_id = users_groups.users_groups_id
                LEFT JOIN users ON users_groups.users_groups_id = users.id
                WHERE users.email = :email";
        $sth = $this->db->prepare($sql);
        $sth->bindParam("email", $input['email']);
        $sth->execute();
        $user = $sth->fetchObject();

        // verify email address.
        if (!$user) {
            $container->get('logger')->info("Error trying to login with email : ".$input['email']);
            return $this->response->withJson(['error' => true, 'message' => 'These credentials do not match our records.']);
        }

        // verify password.
        if (!password_verify($input['password'], $user->password)) {
            $container->get('logger')->info("Error trying to login with password : ".$input['password']);
            return $this->response->withJson(['error' => true, 'message' => 'These credentials do not match our records.']);
        }

        // cek apakah sudah login sebelumnya hari ini untuk user ini
        $absensiSql = "SELECT * FROM users_presensi WHERE user_id = :userID";
        $sth = $this->db->prepare($absensiSql);
        $sth->bindParam("userID", $user->id);
        $sth->execute();
        $absensi = $sth->fetchObject();

        // jika belum absen, masukan user ke absensi
        if(!$absensi){
            $status = 1;
            $absensiSql = "INSERT INTO users_presensi(user_id, statuss) VALUES (:userID, :statuss)";
            $sth = $this->db->prepare($absensiSql);
            $sth->bindParam("userID", $user->id);
            $sth->bindParam("statuss", $status);
            $sth->execute();
            // $absensi = $sth->fetchObject();s
        }

        $settings = $this->get('settings'); // get settings array.

        $token = JWT::encode(['id' => $user->id, 'email' => $user->email, 'level' => $user->groups_level], $settings['jwt']['secret'], "HS256");

// i already set the header here
        return $this->response
        ->withHeader('Access-Control-Allow-Origin', '*')
        ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
        ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
        ->withHeader('Set-Cookie', "token=$token; httpOnly")
        ->withJson(['token' => $token]);

    })->setName('login');

my nuxtjs auth config nuxt.config.js

/*
  ** Nuxt.js modules
  */
  modules: [
    '@nuxtjs/vuetify',
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    '@nuxtjs/pwa',
    '@nuxtjs/eslint-module',
    '@nuxtjs/auth'
  ],
  /*
  ** Axios module configuration
  ** See https://axios.nuxtjs.org/options
  */
  axios: {
  },

  /**
   * set auth middleware
   */
  router: {
    middleware: ['auth']
  },
  auth: {
    strategies: {
      local: {
        endpoints: {
          login: { url: 'http://localhost:8080/login', method: 'post', propertyName: 'token' }
        }
        // tokenRequired: true,
        // tokenType: 'bearer'
      }
    }
  }

method login from login.vue

   loginPost: function () {
      this.$auth.loginWith('local', {
        data: {
          username: this.loginData.username,
          password: this.loginData.password
        }
      })
    }

in postman, the result is token itself, and i think there shouldn't be cors error happen, but who's know.

Loderunner
  • 25
  • 1
  • 7

1 Answers1

1

I don't know about other browsers, but I know that Chrome does not support using localhost in your Access-Control-Allow-Origin header. What you should do is in your dev environment only tell it to accept all origins ->withHeader('Access-Control-Allow-Origin', '*')

The OPTIONS request is what is sent out in preparation for the browser sending out the real request to determine what the CORS rules are.

hostingutilities.com
  • 8,894
  • 3
  • 41
  • 51
  • i edit my code (routes.php) as you sugest, but still does't works even though in response header(in chrome dev) showing `Access-Control-Allow-Headers: content-type` `Access-Control-Allow-Methods: GET, PUT, POST, DELETE, HEAD, OPTIONS` `Access-Control-Allow-Origin: *` also i have tried installing CORS(chrome extension) still my problem exist. – Loderunner Jul 29 '19 at 12:02
  • A couple of things that come to my mind: I know that some back-end frameworks expect all POST requests to have a content type of `application/x-www-form-urlencoded`, and axios sets it to `application/javascript`. I don't know how the `loginWith` function works, but I've had troubled using the Nuxt middleware stuff in my project. I don't remember what those troubles where, but I directly called the `$axios.post` and `$axios.get` functions, and that worked for me. – hostingutilities.com Jul 31 '19 at 01:59
  • You can take a look at this SO answer. Maybe it will help you. https://stackoverflow.com/questions/12630231/how-do-cors-and-access-control-allow-headers-work#answer-12632420 – hostingutilities.com Jul 31 '19 at 01:59
  • Big whoops, i forgot that in my slim application, i'm using corsmiddleware (using tuupola) and i forgot to setting it. – Loderunner Jul 31 '19 at 14:16
  • I'm glad you where able to figure out what the problem was. – hostingutilities.com Jul 31 '19 at 18:43
  • How to fix it with CI4? The route only accept POST method but Nuxt auth always sending the OPTIONS method, so my routes doesn't recognize that and throw error route not found. Thank you – Fahmi Dec 31 '20 at 05:07
  • No Idea. I don't use Code Igniter. – hostingutilities.com Jan 01 '21 at 19:51