Search code examples
laravelvuejs3vuex

Can't get stored user to vuex


I struggle with to store my user session in vuex. Hope somebody can help me out, I tries to build login in to SPA application just to mention that I'm newbee to vue and vuex. I using VUE 3, Vuex, Fortify, Laravel

Login.vue

   <div class="grid login-container">
       <div class="surface-card p-4 shadow-2 border-round w-full lg:w-6">
           <div class="text-center mb-5">
               <img src="images/blocks/logos/hyper.svg" alt="Image" height="50" class="mb-3">
               <div class="text-900 text-3xl font-medium mb-3">Velkommen tilbage</div>
               <span class="text-600 font-medium line-height-3">Har du ingen konto?</span>
               <a class="font-medium no-underline ml-2 text-blue-500 cursor-pointer">Opret her idag!</a>
           </div>
   
           <div>
               <Form :validation-schema="schema" @submit="onSubmit">
   
                   <div class="mb-2">
                       <Field name="email" v-slot="{ field, errorMessage }">
                           <label for="email" class="block text-900 font-medium mb-2">E-mail</label>
                           <InputText v-bind="field" :class="{ 'p-invalid': errorMessage }" type="text" class="w-full" aria-describedby="email-error" />
                           <small class="p-error" id="text-error">{{ errorMessage || '&nbsp;' }}</small>
                       </Field>
                   </div>
   
                   <div class="mb-2">
                       <Field name="password" v-slot="{ field, errorMessage }">
                           <label for="password" class="block text-900 font-medium mb-2">Kodeord</label>
                           <InputText v-bind="field" :class="{ 'p-invalid': errorMessage }" type="text" class="w-full" aria-describedby="password-error" />
                           <small class="p-error" id="text-error">{{ errorMessage || '&nbsp;' }}</small>
                       </Field>
                   </div>
   
                   <div class="flex align-items-center justify-content-between mb-6">
                       <div class="flex align-items-center">
                           <Checkbox id="rememberme" :binary="true" v-model="rembemberMe" class="mr-2"></Checkbox>
                           <label for="rememberme">Husk mig</label>
                       </div>
                       <a href="/reset" class="font-medium no-underline ml-2 text-blue-500 text-right cursor-pointer">Glemt koden?</a>
                   </div>
   
                   <Button type="submit" label="Log ind" icon="pi pi-user" class="w-full"></Button>
               </Form>
           </div>
       </div>
   </div>
</template>

<script setup>
import Checkbox from 'primevue/checkbox';
import { mapActions } from 'vuex';

import { ref } from 'vue'
import { Field, Form } from 'vee-validate';
import { da } from 'yup-locales';
import * as yup from 'yup';

const rembemberMe = ref(false)

yup.setLocale(da);


async function onSubmit(values, actions) {
   const mapActions = mapActions({
       signIn:'auth/login'
   });

   console.log(mapActions.user);
  

   await axios.get('/sanctum/csrf-cookie')

   await axios.post('/api/login', values).then(({ data }) => {
       this.signIn();
   }).catch(({ response }) => {
       console.log(response.data);
   });

   actions.resetForm();
}

const schema = yup.object({
   email: yup.string().email().required().label('E-mail'),
   password: yup.string().required().label('Kodeord'),
});
</script>

<style lang="">

</style> 

resources/js/store/auth.js

import router from '../router'

export default {
   namespaced: true,
   state:{
       authenticated:false,
       user:{}
   },
   getters:{
       authenticated(state){
           return state.authenticated
       },
       user(state){
           return state.user
       }
   },
   mutations:{
       SET_AUTHENTICATED (state, value) {
           state.authenticated = value
       },
       SET_USER (state, value) {
           state.user = value
       }
   },
   actions:{
       login({commit}){
           return axios.get('/api/user').then(({data})=>{
               commit('SET_USER',data)
               commit('SET_AUTHENTICATED',true)
               router.push({name:'Home'})
           }).catch(({response:{data}})=>{
               commit('SET_USER',{})
               commit('SET_AUTHENTICATED',false)
           })
       },
       logout({commit}){
           commit('SET_USER',{})
           commit('SET_AUTHENTICATED',false)
       }
   }
} 

resources/js/store/index.js

import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import auth from './auth'

const store = createStore({
    plugins:[
        createPersistedState()
    ],
    modules:{
        auth
    }
})

export default store

Shows that user are not stored. When I try to login again it says that I'm already logged in enter image description here


Solution

  • You can try to set an action in your vuex store to commit a mutation. For example in js/store/auth.js

    actions: {
            store_login({ commit }, payload) {
                if(payload){
                    commit('SET_USER', payload)
            },
    }
    

    Then in your js view where you call the action, you can dispatch that action and send the payload (data)

    methods: {
        login() {
            axios.post('/api/login', values)
            .then(response => {
                this.$store.dispatch('store_login', data)
            })
    
        }
    }
    

    Now on page load to detect an already logged user and stored in in vuex there are several ways. You can store your data in local storage (I don't prefer this method). You can also get the login from a session.

    Before initilizaing your vuejs app you can create a variable that contains your session in a blade file. For example in your home.blade.php

    @if (Auth::check())
        <script>
                window.authUser = {!! json_encode(Auth::user()) !!}
        </script>
    @endif
    

    Next step is to check if window.authUser exists in your store and use it on your user state

    state() {
            return {
                authenticated: window.authUser ? true : false,
                user: window.authUser ?? null,
            }
        },