Search code examples
laravelvue.jsvuexnuxt.jslaravel-sanctum

Laravel Sanctum - Logged in user best practise


I was wondering what is the best practise for checking that a user is still logged in client side.

Let's say a user logs in. If it's successfull it will be saved in the state, something like this:

axios.post('/login').then(() => {
  this.state.loggedInUser = true
});

Now if a user refreshes their browser, the state is lost, but the laravel_session and XSRF-TOKEN are still available and valid.

Would it make sense to add middleware on every page reload to make a request to retrieve the current logged in user's information? Something like this?:

const authMiddleware = () => {
  axios.get('/user').catch(() => console.error('user is not logged in!'));
};

EDIT

Please be aware that I'm using Sanctum in SPA mode. So there's no tokens.


Solution

  • Using Vue and Vuex for my SPA, I have managed to keep track of authenticated users using the setup below:

    store.js

    The store.js keeps track of the user and isLoggedIn state.

    import { isLoggedIn } from "./utils";
    export default {
        state: {
            isLoggedIn: false,
            user: {}
        },
        mutations: {
            setUser(state, payload) {
                state.user = payload;
            },
            setLoggedIn(state, payload) {
                state.isLoggedIn = payload;
            }
        },
        actions: {
            async loadUser({ commit, dispatch }) {
                if (isLoggedIn) {
                    try {
                        const user = (await axios.get("/user")).data;
                        commit("setUser", user);
                        commit("setLoggedIn", true);
                    } catch (error) {
                        console.log(error)
                    }
                }
            }
        }
    };
    

    utils.js

    The utils.js contains helpers for setting and getting logged in state from local storage.

      
    export function isLoggedIn() {
        return localStorage.getItem("isLoggedIn") == "true";
    }
    
    export function logIn() {
        localStorage.setItem("isLoggedIn", true);
    }
    

    Login.vue

    In the login.vue, i'm calling the logIn() from the utils.js to set the isLoggedIn value in LocalStorage.

    Also, the loadUser action is being dispatched to set the user information in the Vuex store.

    <script>
    import { logIn } from "../utils";
     methods: {
            async login() {
                try {
                    await axios.get("/sanctum/csrf-cookie");
                    await axios.post("/login", {
                        email: this.email,
                        password: this.password
                    });
                    logIn();
                    this.$store.dispatch("loadUser");
                    this.$router.push('/');
                } catch (error) {
                    console.log(error);
                }
            }
        }
    </script>
    

    App.js

    The loadUser action is also being dispatched here to make the user's information available globally if logged in.

    const app = new Vue({
        ...
        async beforeCreate() {
            this.$store.dispatch("loadUser");
        }
    });