Here is how to authenticate users using Vue.js and Firebase
In this comprehensive guide, we will work through building a Vue.js application that uses Firebase for user authentication. The app will allow users to sign up, log in to access protected areas, and log out when done.
To keep things simple, we‘ll assume you have a basic familiarity with Vue.js. If not, I highly recommend going through the Vue.js documentation first, especially the guide on using the CLI and webpack.
We will cover two main topics:
- Using vue-router to handle navigation and protect pages
- Integrating the Firebase authentication API to manage user sign-up and log in
You can reference the complete code on GitHub. Comments explain what‘s happening throughout.
Let‘s dive in!
Application Architecture
Our app will have these pages that users can navigate between:
- Home – Landing page
- Sign Up – Create a new account
- Log In – Enter credentials to authenticate
- Dashboard – Secured area only accessible by logged in users
- 404 – Catch all "page not found"
We‘ll use vue-router to handle navigation between these pages. Some pages will be protected behind authentication using Firebase.
Handling Routes with Vue Router
Vue Router is the official library for routing in Vue.js. We‘ll use it to:
- Map router paths to components
- Navigate between pages
- Secure routes behind authentication
There are two main files that control routing:
main.js
- Import VueRouter
- Initialize it and pass in router config
routes.js
- Define routes as JavaScript objects
- Set path, name, and component for each route
Here is what the router initialization looks like in main.js
:
import VueRouter from ‘vue-router‘
import { routes } from ‘./routes.js‘
Vue.use(VueRouter)
const router = new VueRouter({
routes,
mode: ‘history
})
We import the routes from routes.js
and pass them into the router instance.
Next let‘s take a look at how routes are defined:
routes.js
import Home from ‘./views/Home.vue‘
import SignUp from ‘./views/SignUp.vue‘
export const routes = [
{
path: ‘/‘,
name: ‘home‘,
component: Home
},
{
path: ‘/sign-up‘,
name: ‘signUp‘,
component: SignUp
}
]
The path maps to the URL bar, while name lets us reference the route in code. The matching component is loaded when the route is accessed.
Finally, we need <router-view>
in templates to render components:
<!-- App.vue -->
<template>
<div id="app">
<router-view/>
</div>
</template>
This is where route components will be swapped in when navigation happens.
With this router foundation in place, we can now look at navigating and securing routes.
Securing Routes with Navigation Guards
To protect routes, we‘ll use navigation guards. These allow checking conditions before entering a route, such as:
- Is user authenticated?
- Does user have permission?
There are three types of guards:
- Global – Apply to all routes
- Per-Route – Set on individual route
- In-Component – Inside route component
We‘ll use a global guard so it runs on every navigation:
// Check auth on all routes
router.beforeEach((to, from, next) => {
// Logic here
next()
})
The beforeEach
method takes three arguments:
- to: the route being navigated to
- from: the previous route
- next: call to complete navigation
Inside the hook, we can access route metadata using to.matched
and check conditions.
For example, to protect a route:
const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
if (requiresAuth && !isAuthenticated) {
next(‘/login‘)
} else {
next()
}
By setting meta
fields on routes, we can check if authentication is required. If so, verify the user is logged in before allowing access to the route.
Now let‘s look at adding Firebase for that authentication piece.
Adding Firebase Authentication
Firebase provides backend services out of the box, like a realtime database and cloud storage. Their authentication easily secures sites by handling:
- User signup/login with email/password or federated identity providers
- Access token generation
- Token expiration handling
We‘ll use it handle the authentication flow in our app.
Initialize the Firebase SDK
Get started by signing up for a free Firebase account. You‘ll need to:
- Create a project
- Copy the project configuration
- Paste the config into your app
Make sure to enable Email/Password sign-in method in the Firebase Console. This is what we‘ll be using.
With the SDK initialized, we can now use the Firebase auth API in our Vue app.
Using the Authentication API
The Firebase auth API handles:
- Creating new user accounts
- Generating auth tokens on login
- Managing sessions
We can integrate it directly in our components with:
import Firebase from ‘firebase/app‘
import ‘firebase/auth‘
Firebase.auth().createUserWithEmailAndPassword(email, password)
Firebase.auth().signInWithEmailAndPassword(email, password)
Firebase.auth().signOut()
Let‘s walk through this integration…
We‘ll use the API in two main places:
Sign Up
Allow creating new user accounts with createUserWithEmailAndPassword()
:
// SignUp.vue
methods: {
signUp() {
Firebase.auth()
.createUserWithEmailAndPassword(this.email, this.password)
.then(() => {
this.$router.replace(‘home‘)
})
}
}
On success, we can navigate the user into the app with Vue Router.
Log In
For logging in, we use signInWithEmailAndPassword()
:
// Login.vue
methods: {
login() {
Firebase.auth()
.signInWithEmailAndPassword(this.email, this.password)
.then(() => {
this.$router.replace(‘dashboard‘)
})
}
}
This verifies their credentials and logs them in!
With signup/login handled by Firebase, we can integrate auth into our navigation guard to protect routes.
Wiring Up the Navigation Guard
Recall our global beforeEach
guard:
router.beforeEach((to, from, next) => {
// Check conditions and authorize navigations
})
We need to check if the route requires authentication, and if so, verify the user is logged in.
Firebase gives us a currentUser
object that will be null if no user signed in:
let currentUser = Firebase.auth().currentUser
We can use this in our guard:
router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth)
if (requiresAuth && !currentUser) {
next(‘login‘)
} else {
next()
}
})
Now protected routes will check if there is a current logged in user before granting access!
The last thing we need to do is allow users to log out.
Adding Log Out Functionality
Logging out should destroy the local user session. We can call signOut()
on Firebase auth:
// Header.vue
import Firebase from ‘firebase/app‘
import ‘firebase/auth‘
methods: {
signOut() {
Firebase.auth().signOut()
this.$router.replace(‘login‘)
}
}
Whenever the user clicks "Logout", this will clear credentials and redirect to the login page.
And that completes the authentication flow! Users can now:
- Sign up
- Login
- Access protected routes
- And log out
All powered by Vue + Firebase!
Summary & Next Steps
We went through a basic example of using Firebase authentication with Vue router to handle navigation and protect pages.
Some areas for further improvement:
- Use a state management like Vuex to track authentication state
- Add route-level guards for finer grained control
- Handle pending/loading authentication states
But this covers the core concepts around building secure authentication in a Vue + Firebase application!
The full code again is available on GitHub if you want to use it as a starter kit.
Let me know if you have any other questions!