1

I have laravel 8 installed on a remote server and I'm trying to use sanctum to authenticate from vue cli running in localhost. When I post the login form It returns that i'm authenticated but it doesn't set the cookies in browser. Firefox console says: Cookie “XSRF-TOKEN” has been rejected for invalid domain. The same for the cookie "laravel_Session".

My configuration:

VUE

  import axios from 'axios';
  axios.defaults.withCredentials = true;

  export default {
    name: 'Login',

    data: () => ({
      form:{
        email: '',
        password: ''
      },
      dialog: true,
    }),
    methods: {
      login: function(){
        axios.get('http://xxx.xxx.xxx.xxx:7183/sanctum/csrf-cookie').then(response => {
          console.log(response);
          axios.post('http://xxx.xxx.xxx.xxx:7183/api/login', this.form).then(response => {
              console.log('User signed in!');
              return response;
          }).catch(error => console.log(error, response)); // credentials didn't match
        });
      }
    }

  }

LARAVEL ApiController.php

public function login(Request $request)
    {
      try
      {
        $request->validate([
          'email' => 'email|required',
           'password' => 'required'
        ]);
        $credentials = request(['email', 'password']);
        if (!Auth::attempt($credentials))
        {
          return response()->json([
            'status_code' => 500,
            'message' => 'Unauthorized'
          ]);
        }
        $user = \App\Models\User::where('email', $request->email)->first();
        if ( ! Hash::check($request->password, $user->password, []))
        {
          throw new \Exception('Error in Login');
        }
        $tokenResult = $user->createToken('authToken')->plainTextToken;
        return response()->json([
          'status_code' => 200,
          'access_token' => $tokenResult,
          'token_type' => 'Bearer',
          'user_id' => $user->id,
          'user_name' => $user->name,
        ]);
      }
      catch (Exception $error)
      {
        return response()->json([
          'status_code' => 500,
          'message' => 'Error in Login',
          'error' => $error,
        ]);
      }
    }

config/cors.php

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['api/*', 'sanctum/csrf-cookie'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,


];

Thanks

1 Answers1

1

I'm using sanctum session based authentication in a slightly different configuration, with Angular 11 and Chrome navigator, on localhost and everything is Working Well.

Please make sure to carefully read the documentaion about domain configuration for SPA authentication https://laravel.com/docs/8.x/sanctum#spa-authentication and to properly set these attributes values in your .env file:

  • SESSION_DOMAIN= value here
  • SANCTUM_STATEFUL_DOMAINS= value here
  • SESSION_DRIVER= value here

It seems you put your login endpoint in the API route file. Please consider moving it to the web route file so that to use session based login.

You are free to write your own /login endpoint; however, you should ensure that it authenticates the user using the standard, session based authentication services that Laravel provides. Typically, this means using the web authentication guard.

Also please notice that when using sanctum to authenticate your first-party SPAs you should not use token of any kind, as the documentation said:

Sanctum also exists to provide a simple method of authenticating single page applications (SPAs) that need to communicate with a Laravel powered API. These SPAs might exist in the same repository as your Laravel application or might be an entirely separate repository. For this feature, Sanctum does not use tokens of any kind. Instead, Sanctum uses Laravel's built-in cookie based session authentication services.

So I think you should replace this line

$tokenResult = $user->createToken('authToken')->plainTextToken;

with

$request->session()->regenerate();

Btw I noticed that you are using http status code 500 for Unauthorized. I think 401 would be a better choice. Read more about that here https://httpstatuses.com/

Dharman
  • 30,962
  • 25
  • 85
  • 135
Osymo
  • 11
  • 2