2

I'm trying to build an application using Vue and Laravel. I currently use passport authentication within Laravel for user authentication. However, when I try to make a post request from a vue component using axio, I get 401 unauthorized, even if I am currently logged in.

Here is some example code:

1. Get request from the vue component

    getEvents() {
      axios
        .get("/api/calendar")
        .then(resp => (this.events = resp.data.data))
        .catch(err => console.log(err.response.data));
    }

2. Laravel routes

Route::apiResource('/calendar', 'CalendarController')->middleware('auth:api');

3. Calendar controller associated with the get request above

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return CalendarResource::collection(Calendar::all());
    }

I've spent hours with this issue and everything I have found simply doesn't work. So any help at all is extremely appeciated.

edit:

Extra details

I am using Laravel 5.8.35.

In regards to passport, I am using this documentation laravel.com/docs/5.8/passport and followed the installationm front end quick start and deploying steps.

second edit:

Full code on github

Here is the full project on github incase this can help. https://github.com/CMHayden/akal.app/tree/feature/Calendar

Herb
  • 90
  • 2
  • 8
  • What authentication method do you have in Laravel? Do you use JWT? – Gabriel Willemann Mar 30 '20 at 14:29
  • I use the laravel passport authentication, just following the documentation for it, so I am unsure. I know I use bearer tokens when testing with postman if this helps? – Herb Mar 30 '20 at 14:32
  • Firstly, what version of Laravel are you using? Secondly, which of the various flows from the documentation have you used to authenticate your user i.e. are you using the password grant or the "Consuming Your API With JavaScript" approach, or something different. It would definitely help if you can explain the steps you've gone through in a little more detail. – Rwd Mar 30 '20 at 15:31
  • Hey there, sorry for the lack of information. I am using Laravel 5.8.35. In regards to passport, I am using this documentation https://laravel.com/docs/5.8/passport and followed the installationm front end quick start and deploying steps. – Herb Mar 30 '20 at 15:37

5 Answers5

3

I made some changes to your project, here is the github repository https://github.com/AzafoCossa/ProFix, hope it works.

Open AuthServiceProvider.php file, add Passport::routes() to boot() function and open auth.php file, update 'api' guard from 'driver'=>'token' to 'driver'=>'passport' and finally open Kernel.php file, add this middleware:

'web' => [
   // Other middleware...
   \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
Michał
  • 868
  • 1
  • 10
  • 36
AzafoCossa
  • 874
  • 8
  • 18
1

Please confirm if you've set the meta value for csrf token in the entry html or blade file

<meta name="csrf-token" content="{{ csrf_token() }}">

Also the header for axios in the bootstrap.js file like this

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
Rijosh
  • 1,538
  • 1
  • 8
  • 11
  • I can confirm. My app.blade has the csrf token meta tag and the bootstrap.js does include the axios code. – Herb Mar 30 '20 at 14:37
  • Can you also check if the `auth token` is set and passing with the request header. – Rijosh Mar 30 '20 at 14:44
  • How would I be able to check this? I'm still pretty meh with javascript – Herb Mar 30 '20 at 14:45
  • Open the `Network` tab of your browser. Then filter it using `XHR`. Now when you reload the browser, you can see the http request you've made. On clicking on the request, it will show all the headers set. – Rijosh Mar 30 '20 at 14:51
  • Hey thanks for your help! So yes I can see a cookie which is laravel_token= and a bearer token, and I can see the xsrf token – Herb Mar 30 '20 at 15:32
0

Try adding the correct middleware along with the other suggestions here

'web' => [
    // Other middleware...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

https://laravel.com/docs/5.8/passport#consuming-your-api-with-javascript

Also you shouldn't need these lines that you have in the bootstrap or calendar component. Passport will take care of that for you with http only cookies.

//send Authorization token with each request
axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
brenjt
  • 15,997
  • 13
  • 77
  • 118
  • I have tried this but unfortunately it still doesn't want to work so I don't know what to do anymore – Herb Mar 31 '20 at 12:45
0

All I did to the same problem is:

  1. in User.php, added on head,
'use Laravel\Passport\HasApiTokens;'

then inside the class, added

'HasApiTokens' to the line 'use Notifiable, HasRoles, HasApiTokens;'
  1. In config>auth.php , changed 'driver'=>'token' to 'driver'=>'passport' under 'api' under 'guard'.
'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
            'hash' => false,
        ],
    ],
  1. add the CreateFreshApiToken middleware to your web middleware group in your app/Http/Kernel.php file:
'web' => [
    // Other middleware...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

Nothing else. My axios request was: axios.get('api/cities');

It worked as I wanted. Only component can access the data. But no authenticated or unauthenticated user can access the data through direct url.

-1

If you are storing auth token in cookie then you can do as follows

let token = cookie.get("token");
//send Authorization token with each request
axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
axios
     .get("/api/calendar")
     .then(resp => console.log(resp.data))
     .catch(err => console.log(err))
M.D
  • 270
  • 2
  • 11
  • I have tried this, however, when I check in the network tab I cannot find the authorization header. I also have a small confusion with the Cookie header which contains a laravel_token and a laravel_session and if it is possible something to do with this? Would this also only work through http and maybe just not work locally? Thanks again – Herb Mar 31 '20 at 13:07
  • 1
    The solution above I use with JWT and store the token in the cookie for future authorization. You can check all cookies, session storage, and local storage data in _Application_ tab. Use _Network_ tab to check the response sent from the server. – M.D Mar 31 '20 at 13:24
  • Unfortunetly this solution doesn't seem to want to work for me and I don't even understand why it won't work – Herb Mar 31 '20 at 13:31
  • 1
    See if this works out https://stackoverflow.com/questions/39436509/laravel-passport-scopes/40433000#40433000 – M.D Mar 31 '20 at 14:05