DEV Community

loading...

Vue Js for beginners part 6,Vue routing,guards with Firebase authentication

Tanzim Ibthesam
・7 min read

This is a sequel to my VueJs for BeginnersPart5 Firebase is a tool made by Google for making mobile and web applications.It can be termed as Backend as a service when you are are working with a programming language which requires setting up a server,database etc but with Firebase with minimal setup you can get a backend up and running.Its has a nosql database.
Note one thing: Firebase is definitely not the best solution and it has its cons too but here to make several things clear about Vue authentication we will explain it.
**For Firebase you need to have a google account

If you go to https://firebase.google.com/ if you are logged in from any gmail account you will see
Alt Text
Click the console from here
When you click the console you will see
Alt Text
From here you will select Create a Project
After clicking you will see something like this put name of your project
Alt Text
In next step you will get this
Alt Text

Just click on Create Project.Next this will appear
Here I have selected United States.Click Create project

You project will will be created It might take a few minutes.
Then if you go to https://console.firebase.google.com/
You can see Alt Text
Click on projects name and get started.
After clicking you will see
Alt Text
Assign a nick name and click register app. Then go to console.firebase.google.com
If you dont see this you might see this if you have already made a project previously in Firebase from there
Alt Text

You will see list of firebase projects in console.firebase.google.com
Alt Text
Click your desired project here I am clicking on vue-router
Then you will see
Alt Text
From here on left select FireStore like pointed above.
Alt Text
From here we need to select Create Database
After selecting create database you will see Security rules for Cloud Firestore Alt Text Select test mode for now

Alt Text

After you click enable you are done setting up Firebase.Go to console.firebase.google.com
If from projects you go to vue router and click on Cloud firestore on left then you will see Alt Text

In our vue project go to cli and run npm install firebase
Create a folder named config and inside it create a file named firebase.js
Now go to console.firebase.google.com Then select your project from here select
Alt Text

While you click it you can surely go to Alt Text
If we click on settings icon we will see

Alt Text
Then it will take go to projects setting page if you scroll down below the page you will see
I have blurred out the confidential info but you will have your one
Alt Text
Here you will select the config and copy and paste all. Next you will go to config/firebase.js

import firebase from 'firebase'
import 'firebase/store'
import 'firebase/auth'
//I jave left it blank you will copy and paste it from your firebase config mentioned in pic above
const firebaseConfig = {
    apiKey: "",//
    authDomain: "",
    projectId: "",
    storageBucket: "",
    messagingSenderId: "",
    appId: "",
    measurementId: ""
  };

firebase.initializeApp(firebaseConfig)

const db=firebase.firestore();
//Get access to firebase database
const appAuth=firebase.auth();
//get access to authentication in firebase

export {db,appAuth}
Enter fullscreen mode Exit fullscreen mode

I will create a Login.vue and Register.vue components in components folder
Login.vue
This form is from W3school. Here is how it will be

<div class="container">
    <label for="uname"><b>Username</b></label><br>
    <input type="text" placeholder="Enter Username" name="uname" required><br>

    <label for="psw"><b>Password</b></label><br>
    <input type="password" placeholder="Enter Password" name="psw" required><br>

    <button type="submit">Login</button>
    <label>
      <input type="checkbox" checked="checked" name="remember"> Remember me
    </label>
  </div>

  <div class="container" style="background-color:#f1f1f1">
    <button type="button" class="cancelbtn"><router-link :to="{name:'Register'}" class="cancelbtn">Register</router-link></button>
    <span class="psw"></span>
  </div>
</form>
Enter fullscreen mode Exit fullscreen mode

Style.css
All css here will be in assets/css/style.css I have created a style.css file inside css folder of asset directory
To make style work across all component in src/main.js
import '../src/assets/css/style.css'
The Register.vue will be the same. If you want full form with style click here

Change / directory to Login
So we want that when our app loads instead of home directory we see login page
just go to router/index.js we will do this
{
path: '/',
name: 'login',
component: Login
},

Now if we see on home page we see the login form
Alt Text
Set up way of authentication
Alt Text
As you see in the picture on left you need to click authentication
in next step you will see
Alt Text
From here click set signin method
Then after click you will see a wide range of options.here I will show email password
Alt Text
To enable it
Alt Text
Router replace
In Register.vue

<template>
    <h2>Register Form</h2>

<form @submit.prevent="handleSubmit">


  <div class="container">
    <label for="uname"><b>Email</b></label><br>
    <input type="text" placeholder="Enter Username" v-model="email" required><br>

    <label for="psw"><b>Password</b></label><br>
    <input type="password" placeholder="Enter Password" v-model="password" required><br>

    <button type="submit" class="mainbutton">Register</button>

  </div>

  <div class="container" style="background-color:#f1f1f1">
     <button type="button" class="cancelbtn">
       <router-link class="cancelbtn" :to="{name:'Login'}">Already have an account?Login</router-link>

        </button>

  </div>
</form>
</template>

<script>
import { appAuth,db } from '../config/firebase'
    export default {
        data(){
            return{
               email:'',
               password:'',
            }
        },
        methods:{
               async handleSubmit(){
       try {

            const user=await appAuth.createUserWithEmailAndPassword(this.email,this.password);

            console.log(user);
             this.$router.replace({name:'Home'})
            return user;


       } catch (error) {
           console.log(error);

       }

      }}

    }
</script>

Enter fullscreen mode Exit fullscreen mode

Here we need to put v-model="email" and password" and v-model="password" in both email and password input fields.
appAuth.createUserWithEmailAndPassword(this.email,this.password)
this is the method of registation in firebase
this.$router.replace({name:'Home'}) is what takes us to Home directory.
in Login.vue

<template>
    <h2>Login Form</h2>

<form @submit.prevent="handleSubmit">


  <div class="container">
    <label for="uname"><b>Email</b></label><br>
    <input type="text" placeholder="Enter Username" v-model="email" required><br>

    <label for="psw"><b>Password</b></label><br>
    <input type="password" placeholder="Enter Password" v-model="password" required><br>

    <button type="submit" class="mainbutton">Register</button>

  </div>

  <div class="container" style="background-color:#f1f1f1">
    <button type="button" class="cancelbtn">
        <router-link class="cancelbtn" :to="{name:'Register'}">Dont have an account?Register</router-link>

        </button>

  </div>
</form>
</template>

<script>
import { appAuth,db } from '../config/firebase'
    export default {
        data(){
            return{
               email:'',
               password:'',
            }
        },
        methods:{
               async handleSubmit(){
       try {

            const user=await appAuth.signInWithEmailAndPassword(this.email,this.password);

            console.log(user);
            if(user){
                  this.$router.replace({name:'Home'})
            }

            return user;


       } catch (error) {
           console.log(error);

       }

      }}

    }
</script>
Enter fullscreen mode Exit fullscreen mode

Its the same it takes us to the home directory when we login with proper credentials.
in Home.vue

<template>
  <div class="home">
        <div>Welcome to Home Page</div>
        <div>
          <button @click.prevent="logOut">
            Logout
          </button>
        </div>
  </div>
</template>

<script>
import { appAuth } from '../config/firebase';
export default {
  methods:{
     async logOut(){
         try {
           const logout=await appAuth.signOut();
           console.log(logout);
           this.$router.replace({name:'Login'})
         } catch (error) {
           console.log(error);

         }
       }
  }

}
</script>
Enter fullscreen mode Exit fullscreen mode

Here we logout but we are redirected to Login page
Route Guard
Its a way whether we decide whether the user can access certain routes based on whether the user is authenticated or not.
Now if we see we are authenticated we can still enter Login route and even when we are not authenticated we can still enter Home.vue. So that needs to be stopped.

Make auth guard so only authenticated users can enter the home route
In router folder index.js file
//auth guard
const requireAuth=(to,from,next)=>{
let user=appAuth.currentUser
if(!user){
next({name:'Login'})
}else{
next()
}
}

in Home route this is how we will write

 {
    path:'/home',
    name:'Home',
    component:Home,
    beforeEnter:requireAuth
  }
Enter fullscreen mode Exit fullscreen mode

As a result now only authenticated users can enter the route
Now there are some Problems
Problem One
When you are onto home route and you refresh you redirect back to the login route in your case its the / route and also you can manually go back to the route if you just press /
We will go to main.js file
Solution

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import '../src/assets/css/style.css'
import { appAuth } from './config/firebase'
let app

appAuth.onAuthStateChanged(() => {
  if (!app) {
    app = createApp(App)
      .use(router)
      .mount('#app')
  }
})
Enter fullscreen mode Exit fullscreen mode

At first the app is created then mounted to the DOM.Here firebase keeps the app on hold until connection is established with the backend.It first hears whether user is logged in or not that is it observes the change of initial auth state change. It is not render unless connection is established with the backend.

Now when we refresh or go back it keeps us on home page.

Problem two-It still redirects us to Login and register routes when we enter them manually
Solution go to router folder in index.js file

const notrequireAuth=(to,from,next)=>{
  let user=appAuth.currentUser
  if(user){
    next({name:'Home'})
  }else{
    next()
  }

}
Enter fullscreen mode Exit fullscreen mode

So here we see the function is that if user is authenticated he will go to Home route and if he is not than to other

{
    path: '/',
    name: 'Login',
    component: Login,
    beforeEnter:notrequireAuth
  },

  {
    path:'/register',
    name:'Register',
    component:Register,
    beforeEnter:notrequireAuth
  }
Enter fullscreen mode Exit fullscreen mode

So its a huge blog and it covers a lot you need to know about Vue routing.Hopefully will cover Vuex in next part.

Discussion (0)