diff --git a/front/package.json b/front/package.json
index e4355926877f4c633ba0298e2a1ec8341ea16da9..4dd9ba87e7e81fa7a7b374866bfe8d2235a4b4bc 100644
--- a/front/package.json
+++ b/front/package.json
@@ -8,8 +8,10 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "axios": "^0.18.0",
     "pug": "^2.0.3",
     "register-service-worker": "^1.5.2",
+    "semantic-ui-vue": "^0.7.0",
     "vue": "^2.5.22",
     "vue-router": "^3.0.1",
     "vuex": "^3.0.1"
diff --git a/front/public/img/wallpaper.jpg b/front/public/img/wallpaper.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..8c175c8dab03ba5ffdf4338e6c08addc4fadabee
Binary files /dev/null and b/front/public/img/wallpaper.jpg differ
diff --git a/front/public/index.html b/front/public/index.html
index 5514f8289d3904c9eb922fe1cbc7fe46c3a1d637..35239811aa290bb59e428c968efb3c5e1fcd110f 100644
--- a/front/public/index.html
+++ b/front/public/index.html
@@ -5,9 +5,11 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.0/semantic.min.css">
     <title>front</title>
   </head>
   <body>
+    <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
     <noscript>
       <strong>We're sorry but front doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
     </noscript>
diff --git a/front/src/App.vue b/front/src/App.vue
index ab8fe3c0a0586e85f4430d14ed127a1e7fcb87d6..913958c12c9e304327080cff49d1006fd02c8183 100644
--- a/front/src/App.vue
+++ b/front/src/App.vue
@@ -1,31 +1,25 @@
-<template>
-  <div id="app">
-    <div id="nav">
-      <router-link to="/">Home</router-link> |
-      <router-link to="/about">About</router-link>
-    </div>
-    <router-view />
-  </div>
+<template lang="pug">
+  .app
+    NavBar
+    .ui.grid
+      .three.wide.column
+      .ten.wide.column
+        router-view
+      .three.wide.column
+      //- notifications
 </template>
 
-<style>
-#app {
-  font-family: "Avenir", Helvetica, Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
-}
-#nav {
-  padding: 30px;
+<script>
+import NavBar from "@/components/NavBar.vue";
+export default {
+  name: "App",
+  components: {
+    NavBar,
+  },
 }
+</script>
 
-#nav a {
-  font-weight: bold;
-  color: #2c3e50;
-}
 
-#nav a.router-link-exact-active {
-  color: #42b983;
-}
+<style>
+
 </style>
diff --git a/front/src/components/NavBar.vue b/front/src/components/NavBar.vue
new file mode 100644
index 0000000000000000000000000000000000000000..21c0fc56253cfbe2bab575ec82a2e7eec7e1b2ae
--- /dev/null
+++ b/front/src/components/NavBar.vue
@@ -0,0 +1,49 @@
+<template lang="pug">
+  sui-menu(pointing)
+    router-link(is="sui-menu-item", to="/") Home
+    router-link(v-if="user", is="sui-menu-item", to="/characters") Characters
+    sui-menu-menu(v-if="!user", position="right")
+      sui-menu-item
+        sui-input(transparent, type="text", placeholder="username", v-model="username")
+        sui-input(transparent, type="password", placeholder="password", v-model="password")
+        sui-button(@click="login") Login
+    sui-menu-menu(v-else, position="right")
+      sui-menu-item {{ user.username }}
+      sui-menu-item
+        sui-button(@click="logout") Logout
+</template>
+
+<script>
+export default {
+  name: "NavBar",
+  data() {
+    return {
+      username: "",
+      password: "",
+    }
+  },
+  computed: {
+    user() {
+      return this.$store.state.user;
+    }
+  },
+  created() {
+    this.$store.dispatch("login");
+  },
+  methods: {
+    login() {
+      this.$store.dispatch("authRequest", {
+        username: this.username,
+        password: this.password
+      });
+    },
+    logout() {
+      this.$store.dispatch("logout");
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>
diff --git a/front/src/http.js b/front/src/http.js
new file mode 100644
index 0000000000000000000000000000000000000000..1b9024fa048047ba493fb2b498a768b83d98408d
--- /dev/null
+++ b/front/src/http.js
@@ -0,0 +1,12 @@
+import axios from "axios";
+
+export default function() {
+  return axios.create({
+    baseUrl: "http://localhost:3000/",
+    timeout: 1000,
+    headers: {
+      Authorization: localStorage.getItem("token"),
+      "Content-Type": "application/json"
+    }
+  });
+}
diff --git a/front/src/main.js b/front/src/main.js
index 9466dcc769bed98c9fd9c1d761638576262251ba..014159cef83c8f0608734bde846bc031869d2326 100644
--- a/front/src/main.js
+++ b/front/src/main.js
@@ -3,8 +3,10 @@ import App from "./App.vue";
 import router from "./router";
 import store from "./store";
 import "./registerServiceWorker";
+import SuiVue from "semantic-ui-vue";
 
 Vue.config.productionTip = false;
+Vue.use(SuiVue);
 
 new Vue({
   router,
diff --git a/front/src/store.js b/front/src/store.js
index bb02ce2d2c3ace184b1b4d9f5e98b67d9973b3d8..b0e6bcc28539f2afc023768bae4ac71dd8aca903 100644
--- a/front/src/store.js
+++ b/front/src/store.js
@@ -1,10 +1,53 @@
 import Vue from "vue";
 import Vuex from "vuex";
+import http from "@/http";
 
 Vue.use(Vuex);
 
 export default new Vuex.Store({
-  state: {},
-  mutations: {},
-  actions: {}
+  state: {
+    status: "",
+    user: null
+  },
+  getters: {
+    isAuthenticated: state => !!localStorage.getItem("token") && !!state.user,
+    authStatus: state => state.status,
+    user: state => state.user
+  },
+  mutations: {
+    ["AUTH_REQUEST"]: state => (state.status = "loading"),
+    ["AUTH_SUCCESS"]: (state, user) => {
+      state.status = "success";
+      state.user = user;
+    },
+    ["AUTH_ERROR"]: state => (state.status = "error"),
+    ["LOGOUT"]: state => {
+      state.user = null;
+      state.status = "success";
+    }
+  },
+  actions: {
+    authRequest: ({ commit }, credentials) => {
+      commit("AUTH_REQUEST");
+      http()
+        .post("http://localhost:3000/users/authenticate", credentials)
+        .then(res => {
+          localStorage.setItem("token", res.data.token);
+          commit("AUTH_SUCCESS", res.data);
+        })
+        .catch(() => commit("AUTH_ERROR"));
+    },
+    logout: ({ commit }) => {
+      localStorage.removeItem("token");
+      commit("LOGOUT");
+    },
+    login: ({ commit }) => {
+      if (localStorage.getItem("token")) {
+        http()
+          .get("http://localhost:3000/users/me")
+          .then(res => commit("AUTH_SUCCESS", res.data))
+          .catch(() => commit("AUTH_ERROR"));
+      }
+    }
+  }
 });