0

I have an rest api that, depending on whether the user is authorized or not, issues different products /api/products. This api for a mobile application, I carry out authorization through a bearer token with Sanctum. To process requests from any users and, depending on whether there is a token or not, display goods.

My custom middleware for api

public function handle(Request $request, Closure $next): Response
    {
        if ( $request->bearerToken() && Auth::guard('sanctum')->user() )
            Auth::setUser( Auth::guard('sanctum')->user() );

        return $next($request);
    }

Next, it took not only api but also a website that will use this api, which is intended for a mobile application. Decided to use the usual php approach using vue components. Its Breeze & Blade with Fortify and Vue. As far as I understand, if the user is authorized through the website, cookies with authorization come to him and they must be applied to Ajax requests.

My axios request from vue component to /api/products. If the user is authorized through the website, then a cookie is applied and sent

const instance = axios.create({
    timeout: 2000,
   
    //My cookie included
    withCredentials: true,

    headers: {
      'Access-Control-Allow-Origin': '*',
      'Content-Type': 'application/json',
      'Access-Control-Allow-Credentials' : true
       },

    //With token works. Middleware understands that the user is authorized
    //headers: {'Authorization': 'Bearer '+'1|XedL48l1TU5KomRxix6xFrsm0v7jw5eTbHzfpoGC'}
  });

  instance
      .post("/api/products",
          {
            data: example_data,

          }, )
      .then(response => {
        console.log(response.data)
      });

The problem is that the middleware does not understand the cookies that come with the axios request. Middleware can't figure out if I'm authorized or not through the cookies attached to requests. It understands only the token in header, it works with the token.The documentation says that the Sanctum middleware understands the cookies that are attached to the request, but I do not use the middleware sanctum. Is it possible to implement it somehow, so that the authorized user's cookies would be understood by my custom middleware and not just the token?

1 Answer 1

1

I'm the one who answers your first questions.

You do not need to pass things like that when doing request from your front-end which is already authenticated through session.

All you have to is make sure to set with axios with credentials under resources/js/bootstrap.js

import axios from 'axios'
window.axios = axios

window.axios.defaults.withCredentials = true
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'

Then you could simply call the end-point from vue template and the middleware would be able to idenfity authenticated request or not

<script setup>
import { onMounted } from 'vue'

async function getProducts() {
    try {
        const { data } = await axios.get(`/api/products`)
        console.log( data )
    } catch (error) {
        console.log( error.response.message ?? error.message )
    }
}

onMounted( () => {
    getProducts()
})

</script>

Just a side note, if you authenticating via API tokens, make sure to pass Accept: application/json on your header request

EDIT

your app/Http/Kernel.php should have this lines in $middlewareGroups

protected $middlewareGroups = [
    'web' => [
        .
        .
        .
    ],

    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you! But still doesn't work. The browser has debugging of all XHR requests, that vue sends. My request contains cookies laravel_session, remember_web... and XSRF-TOKEN if sent from an authorized user, but the middleware doesn't understand that the request came from an authorized user.I can’t understand why this is happening, because Laravel should understand session cookies
there is probably some misconfiguration with your app somewhere, could be in config auth, session, cors, sanctum or maybe kernel, trying checking the docs for spa auth laravel.com/docs/10.x/sanctum#spa-authentication,
Additionally, my advise would be to isntall clean laravel project with breeze vue php artisan breeze:install vue --ssr and compare all the configs with your application config
This is a clean install, not spa, but the usual laravel Breeze & Blade, vue is connected as a component. In the middleware itself, I can see the cookies request()->cookie() they are present, all those sent by axios. At the beginning, I thought it was the wrong axios job. I don’t understand why Laravel doesn’t want to use cookies for authorization
did you add \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class on $middlewareGroups api inside kernel?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.