DEV Community

Cover image for Authenticating a Vue SPA is easy with Laravel Sanctum

Authenticating a Vue SPA is easy with Laravel Sanctum

Andrew Schmelyun on May 11, 2020

Released earlier this year, Laravel Sanctum (formerly Laravel Airlock), is a lightweight package to help make authentication in single-page or nati...
Collapse
 
samora92 profile image
samora92

I did all these steps, but when i am trying to get user data i get Unauthenticated error
routes/api.php

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});
Enter fullscreen mode Exit fullscreen mode

home.vue

<script>
import axios from "axios";
axios.defaults.withCredentials = true;
axios.defaults.baseURL = "http://localhost:8000/";

export default {
 mounted(){
     axios.get("/api/user").then((response)=>{
       console.log(response);
     })
 }
}
</script>
Enter fullscreen mode Exit fullscreen mode

I do not know if i did any thing wrong ?

Collapse
 
maxeze profile image
Maximiliano Basoalto

Happening the same to me :(

Collapse
 
samora92 profile image
samora92 • Edited

I solved it , in your Providers/RouteServiceProvider.php, change the mapApiRoutes function from middleware(['api']) to middleware(['web'])

protected function mapApiRoutes()
    {
        Route::prefix('api')
            ->middleware('web')
            ->namespace($this->namespace)
            ->group(base_path('routes/api.php'));
    }
Enter fullscreen mode Exit fullscreen mode

Hope this helping you.

Thread Thread
 
harmlezprinze profile image
Olami Lekan

Great work, please i will like to have a little chat with u man

Thread Thread
 
aymenalhattami profile image
Ayman Alhattami

This is not a good solution,

Thread Thread
 
aymenalhattami profile image
Ayman Alhattami

The solution is to set value for

SANCTUM_STATEFUL_DOMAINS='127.0.0.1:3000'
Enter fullscreen mode Exit fullscreen mode

in the .env file

Collapse
 
alyve profile image
Alyve

Hi. Thank you for this amazing article. ☺️
Just got a question:

    axios.get('/sanctum/csrf-cookie').then(response => {
        axios.post('/login', this.formData).then(response => {
            this.getSecrets();
        }).catch(error => console.log(error)); // credentials didn't match
    });

Why are you asking for a CSRF token right here ? I'm asking because I don't do that and I'm interested about learning something else here. 🤗
Thanks !

Collapse
 
coderincode profile image
Coder

when I want to use it with nuxt js I have many problems . I reveive data correctly from api but there is anything to do. how can I debug it. this is my setting in nuxt:


auth: {
        strategies: {
            local: {
                endpoints: {
                    login: { url: '/api/auth/login', method: 'post', propertyName: false },
                    user: { url: '/api/auth/me', method: 'get', propertyName: false }
                },
               tokenRequired: false,
               tokenType: false
            }
        },
        localStorage: false
    },

this is my login.vue

methods:{
           async submit (){
                try{
                    await this.$axios.$get('/sanctum/csrf-cookie');

                    await this.$auth.loginWith('local' ,{data: this.form});

                    console.log(111);
                }catch (e) {
                    console.log(e);
                }
            }
                }

this is login api:

public function action(LoginRequest $request){

        $user = User::query()->where('email', $request->email)->first();

        if (! $user || ! Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'email' => ['The provided credentials are incorrect.'],
            ]);
        }

        return (new PrivateUserResource($user))
            ->additional([
                'meta' => [
                    'token' => $user->createToken($request->email)->plainTextToken
                ]
            ]);
    }
Collapse
 
lexiebkm profile image
Alexander B.K.

Suppose there are 2 apps :

  • app 1 deals with human resource development (HRD) that already exists in the client
  • app 2 that I am developing, deals with performance management system for every employee in the client, but in different domain.

My app (app 2) will provide API that can be consumed by app 1, i.e app 1 can post employee records to my app (post/put request) as well as retrieve performance data (get request) from my app.
Is Sanctum adequate for this kind of apps ? I have read both Passport (OAuth 2) and Sanctum, but am still not sure which one I will pick.

Collapse
 
dylanglockler profile image
Dylan

Nice write up. I have Larave/Sanctum working well with Quasar with Vuex - wondering if there is a good way to know on the vue side if the user is authenticated - or perhaps at the login process I just need to track that state myself. I'm loading their user data into Vuex but on refresh it's lost, while the authentication is maintained - I'd like to query that auth state to then re-query the user details.

Collapse
 
koiki13 profile image
Koiki Damilare Solomon

Can I use this with a project that is not SPA

Collapse
 
pimhooghiemstra profile image
Pim Hooghiemstra

Great article, gets me ready to add this to my SPA too! I noticed a small error in the text where you write about the laravel ui package. I think this was first added in Laravel 6.