4
\$\begingroup\$

If the user/visitor has access to the API route, then the status code will 200, else 401. I know that I can user Vue navigation guards, but I will need to use Vuex.

This way is much simpler and faster, what do you think, is it a right way to protect Vue page from unauthenticated users?

    <template>
    <v-container>
        <div v-if="isAuthenticated === false">loading</div>
        <div v-else>Protected Profile Page</div>
    </v-container>
</template>

<script>
    export default {
        data () {
            return {
                isAuthenticated : false,
            }
        },
        beforeCreate: async function() {
            axios.get('api/user', {})
                 .then(res => {
                     this.isAuthenticated = true;
                 }).catch(err => {
                this.isAuthenticated = false;
                this.$router.push('/login');
            })
        },
        created () {
            console.log('isAuthenticated', this.isAuthenticated) // return false
        }
    }
</script>
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

In theory what you do here works, but there are a few caveats:

  • You declared your beforeCreate lifecycle hook as async, but you do not await any statement. It serves no particular purpose.
  • Be very careful with declaring lifecycle hooks as asynchronous, because when you await something that rejects the promise, you cannot catch the resulting error. You will end up with a component that cannot render, which makes for a bad user experience.
  • Vue router has global navigation guards, but you can actually also just declare a route guard on the component that is being mounted. They are called in-component guards and one that would be useful to you is beforeRouteEnter. You can redirect someone to the login page before this component even renders.
beforeRouteEnter (to, from, next) {
  axios.get('api/user', {})
    .then(_ => {
      next();
    }).catch(_ => {
      next('/login');
    });
}
  • While you could rely on the endpoint returning an error of some sort, there are more reasons why your endpoint might return an error. Some of those reasons might include rate limiting of the api, a bad connection or an overloaded server. Having someone redirect to the login page everytime that happens will get old fast. If you want to protect multiple components this way, you are spamming your server with unnecessary api calls. Also keep in mind that frontend security is essentially no security at all. You only "protect" stuff in the frontend to help the user experience, but your api should never return data or save data from a user that has no permissions/is not logged in. You are likely better off catching 403 errors and only redirecting them, while showing a generic error message on anything else.

You have already mentioned it, but you could use Vuex for state management. Arguably, something like "isAuthenticated" is not something every singular component should manage. Setting up a vuex store is usually less than 5 minutes work and I would still recommend managing something like that there.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.