diff --git a/viz-dev-frontend/src/guard.js b/viz-dev-frontend/src/guard.js
new file mode 100644
index 0000000000000000000000000000000000000000..92f6087e9b73aa4cad6f3cb793242ea912fcc158
--- /dev/null
+++ b/viz-dev-frontend/src/guard.js
@@ -0,0 +1,67 @@
+import store from './store';
+import api from './api';
+
+async function getCurrentSession() {
+  try {
+    const response = await api.get('/me/', { ignoreUnauthorizedError: true });
+    return response.data;
+  } catch (err) {
+    return null;
+  }
+}
+
+export async function requireLogin(_, from, next) {
+  const redirectTo = { name: 'Home', replace: true };
+
+  if (store.getters['auth/isLoggedIn']) {
+    next();
+    return;
+  }
+
+  const user = await getCurrentSession();
+  if (user) {
+    store.commit('auth/setUser', user);
+    next();
+    return;
+  }
+
+  next(redirectTo);
+}
+
+export async function requireAdmin(_, from, next) {
+  const redirectTo = { name: 'Home', replace: true };
+
+  if (store.getters['auth/isAdmin']) {
+    next();
+    return;
+  }
+
+  const user = await getCurrentSession();
+  if (user) {
+    if (user.role === 'admin') {
+      store.commit('auth/setUser', user);
+      next();
+      return;
+    }
+  }
+
+  next(redirectTo);
+}
+
+export async function requireGuest(_, from, next) {
+  const redirectTo = { name: 'Home', replace: true };
+
+  if (store.getters['auth/isLoggedIn']) {
+    next(redirectTo);
+    return;
+  }
+
+  const user = await getCurrentSession();
+  if (user) {
+    store.commit('auth/setUser', user);
+    next(redirectTo);
+    return;
+  }
+
+  next();
+}
diff --git a/viz-dev-frontend/src/modules/auth.js b/viz-dev-frontend/src/modules/auth.js
index 805c6b54b24094aa783384543d22ae2ebcb223a3..7b439dad5320e4b09c0f3d9e6ad565df26cc9775 100644
--- a/viz-dev-frontend/src/modules/auth.js
+++ b/viz-dev-frontend/src/modules/auth.js
@@ -11,6 +11,9 @@ export default {
     isLoggedIn(state) {
       return !!state.user;
     },
+    isAdmin(state) {
+      return !!state.user && (state.user.role === 'admin');
+    },
   },
   mutations: {
     /* eslint-disable no-param-reassign */
diff --git a/viz-dev-frontend/src/router.js b/viz-dev-frontend/src/router.js
index 3aebefbddf971a5939220a763f9539446de6077a..a5de307e3889601a6ab6dfd5ced5168dc788ddd9 100644
--- a/viz-dev-frontend/src/router.js
+++ b/viz-dev-frontend/src/router.js
@@ -1,5 +1,6 @@
 import Vue from 'vue';
 import Router from 'vue-router';
+import { requireAdmin, requireGuest, requireLogin } from './guard';
 import Home from './views/Home.vue';
 import ManageAccount from './views/ManageAccount.vue';
 import Login from './views/Login.vue';
@@ -14,36 +15,32 @@ export default new Router({
   routes: [
     {
       path: '/',
-      name: 'home',
+      name: 'Home',
       component: Home,
     },
-    {
-      path: '/about',
-      name: 'about',
-      // route level code-splitting
-      // this generates a separate chunk (about.[hash].js) for this route
-      // which is lazy-loaded when the route is visited.
-      component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
-    },
     {
       path: '/manage',
       name: 'ManageAccount',
       component: ManageAccount,
+      beforeEnter: requireAdmin,
     },
     {
       path: '/login',
       name: 'Login',
       component: Login,
+      beforeEnter: requireGuest,
     },
     {
       path: '/edit',
       name: 'Edit',
       component: Edit,
+      beforeEnter: requireLogin,
     },
     {
       path: '/edit_data',
       name: 'Edit_Data',
       component: EditData,
+      beforeEnter: requireLogin,
     },
   ],
 });