diff --git a/back/config.template.yml b/back/config.template.yml
index 0d70e81d91d820482d1ae0fcdbdd6eecf345a906..41ffb4ca18177edc9b6a2dce715cdec7f593b7c8 100644
--- a/back/config.template.yml
+++ b/back/config.template.yml
@@ -1,6 +1,7 @@
 port: 3000
 secret: GENERATE
 cryptRounds: 10
+jwtExpiresInMinutes: 1440
 maxActionPoints: 480
 initAttributesPoints: 15
 attributes:
diff --git a/back/data/lastActionPointsUpdate b/back/data/lastActionPointsUpdate
index 43a8da0c143d1e7048c43fa109cd24e757def613..96188cedf835a65f1ddafeb6a61a76f35b3be50b 100644
--- a/back/data/lastActionPointsUpdate
+++ b/back/data/lastActionPointsUpdate
@@ -1 +1 @@
-Sun Feb 17 2019 01:14:58 GMT+0100 (Central European Standard Time)
\ No newline at end of file
+Mon Feb 18 2019 21:20:58 GMT+0100 (Central European Standard Time)
\ No newline at end of file
diff --git a/back/index.js b/back/index.js
index 30bafd702e094663c6ee3b43593dd2c366b79538..aca5f5cf058ebe6cdecfd49061fd6ae416dd1f32 100644
--- a/back/index.js
+++ b/back/index.js
@@ -4,47 +4,34 @@ const session = require('express-session');
 const bodyParser = require('body-parser');
 const mongoose = require('mongoose');
 const morgan = require('morgan');
-const mongoDBStore = require('connect-mongodb-session')(session);
+const cors = require('cors');
 
 // Config
 const config = require('js-yaml').safeLoad(fs.readFileSync('./config.yml', 'utf8'));
 // Middlewares
-const userLoader = require('./middlewares/userLoader');
+const loader = require('./middlewares/loader');
 const loginChecker = require('./middlewares/loginChecker');
 // Utils
-const render = require('./utils/render');
 const { warn, error } = require('./utils/notifications');
 // Routes
-const authRouter = require('./routes/auth');
+const usersRouter = require('./routes/users');
 const charactersRouter = require('./routes/characters');
 // Crons
 require('./utils/crons');
 
 // Configuration
 const app = express();
-const store = new mongoDBStore({
-  uri: 'mongodb://localhost/rolegame',
-  collection: 'sessions'
-});
-store.on('error', function(error) {
-  console.error(error);
-});
-app.set('view engine', 'pug');
 
 // Middlewares
 app.use(morgan('tiny'));
-app.use(session({ secret: config.secret, resave: false, saveUninitialized: false, store }));
-app.use(bodyParser.urlencoded({ extended: false }));
-app.use('/media', express.static('media'));
-app.use(userLoader);
+app.use(cors())
+app.use(bodyParser.json());
+app.use(loader);
 app.use(loginChecker);
 
 // Routes
-app.get('/', async (req, res) => {
-  return render(req, res, 'home');
-});
-app.use('/auth', authRouter);
-app.use('/characters', charactersRouter);
+app.use('/users', usersRouter);
+// app.use('/characters', charactersRouter);
 
 mongoose.connect('mongodb://localhost/rolegame', err => {
   if (err) {
diff --git a/back/middlewares/loader.js b/back/middlewares/loader.js
new file mode 100644
index 0000000000000000000000000000000000000000..d82e0d9828fa66411e5c268775223396f910951f
--- /dev/null
+++ b/back/middlewares/loader.js
@@ -0,0 +1,9 @@
+const User = require('../models/user');
+
+module.exports = async (req, res, next) => {
+  if (req.get('Authorization')) {
+    req.user = await User.findOne({ token: req.get('Authorization')});
+    console.log(req.user);
+  }
+  next();
+};
diff --git a/back/middlewares/loginChecker.js b/back/middlewares/loginChecker.js
index 7c59919cfc7e90b1a02dbc1f7c0dabb311d65deb..c340d61cc2173c381671a07410b7e7748e2157fc 100644
--- a/back/middlewares/loginChecker.js
+++ b/back/middlewares/loginChecker.js
@@ -1,7 +1,5 @@
 module.exports = (req, res, next) => {
-  if (req.session.user || ['/', '/auth/signup', '/auth/login'].includes(req.url)) {
-    next();
-  } else {
-    return res.redirect('/auth/signup');
-  }
+  console.log(req.url);
+  if (!req.user && !['/users', '/users/authenticate'].includes(req.url)) return res.status(401).json({ error: 'Authentication needed'});
+  return next();
 };
\ No newline at end of file
diff --git a/back/middlewares/userLoader.js b/back/middlewares/userLoader.js
deleted file mode 100644
index d72167ff221694b08233a25ecc32368452945103..0000000000000000000000000000000000000000
--- a/back/middlewares/userLoader.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const User = require('../models/user');
-
-module.exports = (req, res, next) => {
-  if (req.session.user) {
-    User.findById(req.session.user._id, (err, user) => {
-      err ? error(req, res, 'Error fetching user', err) : null;
-      req.session.user = user;
-      next();
-    });
-  } else {
-    next();
-  }
-};
diff --git a/back/models/user.js b/back/models/user.js
index 5a7dfc7ff73e21fffbb02d6930774eebd9f6713f..cd466e86d558052b324d81bfced42f06c3dc8832 100644
--- a/back/models/user.js
+++ b/back/models/user.js
@@ -2,11 +2,10 @@ const mongoose = require('mongoose');
 const Notification = require('./notification');
 
 const User = new mongoose.Schema({
-  firstName: { type: String, required: true },
-  lastName: { type: String, required: true },
   username: { unique: true, type: String, lowercase: true },
   email: { type: String, required: true },
   passwordHash: { type: String },
+  token: { type: String },
   notifications: [Notification],
 });
 
diff --git a/back/package.json b/back/package.json
index 13cee154e1e8b94f4e6ef1531713a6c12883bfde..09e1a1d699af98b6fe3bbe256f3db999d298f41c 100644
--- a/back/package.json
+++ b/back/package.json
@@ -5,16 +5,15 @@
   "dependencies": {
     "bcrypt": "^3.0.4",
     "body-parser": "^1.18.3",
-    "connect-mongodb-session": "^2.1.1",
+    "cors": "^2.8.5",
     "eslint": "^5.13.0",
     "express": "^4.16.4",
-    "express-session": "^1.15.6",
     "js-yaml": "^3.12.1",
     "mongoose": "^5.4.11",
     "morgan": "^1.9.1",
     "node-cron": "^2.0.3",
     "nodemon": "^1.18.10",
-    "pug": "^2.0.3",
+    "rand-token": "^0.4.0",
     "random": "^2.0.13"
   }
 }
diff --git a/back/routes/auth.js b/back/routes/auth.js
deleted file mode 100644
index 16c14a8298da5119081f7f092ffc669b864a5ef2..0000000000000000000000000000000000000000
--- a/back/routes/auth.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const express = require('express');
-const bcrypt = require('bcrypt');
-const User = require('../models/user');
-const render = require('../utils/render');
-const { warn, error } = require('../utils/notifications');
-
-const router = express.Router();
-
-router.get('/signup', (req, res) => {
-  return render(req, res, 'signup');
-});
-
-router.post('/signup', (req, res) => {
-  const passwordHash = bcrypt.hashSync(req.body.password, config.cryptRounds);
-  User.create(req.body, (err, user) => {
-    err ? error(req, res, 'Error creating user', err) : null;
-    user.passwordHash = passwordHash;
-    user.save();
-    req.session.user = user;
-    return res.redirect('/');
-  });
-});
-
-router.post('/login', (req, res) => {
-  if (!req.body.username || !req.body.password) {
-    return res.redirect('/auth/signup');
-  } else if (req.session.user) {
-    error(req, res, 'User already logged in', 'You must logout before log in.')
-  } else {
-    User.findOne({ username: req.body.username }, (err, user) => {
-      err ? error(req, res, 'Error fetching user', err) : null;
-      if (bcrypt.compareSync(req.body.password, user.passwordHash)) {
-        req.session.user = user;
-        return res.redirect(req.query.nextUrl || '/');
-      } else {
-        error(req, res, 'Bad credentials')
-        return res.redirect('/auth/signup');
-      }
-    });
-  }
-});
-
-router.post('/logout', (req, res) => {
-  req.session.destroy();
-  return res.redirect('/');
-});
-
-module.exports = router;
\ No newline at end of file
diff --git a/back/routes/characters.js b/back/routes/characters.js
index 91a3e76cfc7b8449318b2d0739b9a7c077e34e50..bf48dc3bbeba15c83d978089388ed3329b1ed005 100644
--- a/back/routes/characters.js
+++ b/back/routes/characters.js
@@ -2,7 +2,6 @@ const express = require('express');
 const fs = require('fs');
 const { initAttributesPoints, costTable, attributes, maxActionPoints, maxCharactersNumber } = require('js-yaml').safeLoad(fs.readFileSync('./config.yml', 'utf8'));
 const Character = require('../models/character');
-const render = require('../utils/render');
 const { warn, error } = require('../utils/notifications');
 
 const router = express.Router();
@@ -13,7 +12,8 @@ router.get('/', async (req, res) => {
   // TODO: Login required
   const avatars = fs.readdirSync('media/avatars');
   Character.find({ user: req.session.user._id }, (err, characters) => {
-    return render(req, res, 'characters', { characters, avatars, initAttributesPoints, maxActionPoints });
+    if (err) return res.status(400).json({ error: err });
+    return res.json(characters);
   });
 });
 
diff --git a/back/routes/users.js b/back/routes/users.js
new file mode 100644
index 0000000000000000000000000000000000000000..9b057072ba9efa18d6ec5dbd290ebb781bfc76a7
--- /dev/null
+++ b/back/routes/users.js
@@ -0,0 +1,40 @@
+const express = require('express');
+const bcrypt = require('bcrypt');
+const randToken = require('rand-token');
+const User = require('../models/user');
+const { warn, error } = require('../utils/notifications');
+const config = require('js-yaml').safeLoad(require('fs').readFileSync('./config.yml', 'utf8'));
+
+const router = express.Router();
+
+router.post('/', (req, res) => {
+  const passwordHash = bcrypt.hashSync(req.body.password, config.cryptRounds);
+  const token = randToken.generate(32);
+  User.create({
+    username: req.body.username,
+    email: req.body.email,
+    passwordHash,
+    token
+  }).then(user => {
+    delete user.passwordHash;
+    delete user.token;
+    return res.status(201).json(user);
+  }).catch(err => res.status(400).json({ error: err }));
+});
+
+router.post('/authenticate', (req, res) => {
+  if (!req.body.username || !req.body.password) return res.status(400).json({ error: 'Credentials required' });
+  User.findOne({ username: req.body.username }, (err, user) => {
+    if (err) return res.status(500).json({ error: err });
+    if (!user) return res.status(404).json({ error: "User not found"});
+    if (bcrypt.compareSync(req.body.password, user.passwordHash)) return res.json({ token: user.token });
+    return res.status(400).json({ error: "Bad password" }); 
+  });
+});
+
+router.get('/me', (req, res) => {
+  // User required
+  return res.json(req.user);
+})
+
+module.exports = router;
\ No newline at end of file
diff --git a/back/utils/render.js b/back/utils/render.js
deleted file mode 100644
index 3ebc53514e9e8890d2cdfcf9e1407b5d0ef87976..0000000000000000000000000000000000000000
--- a/back/utils/render.js
+++ /dev/null
@@ -1,24 +0,0 @@
-const render = (req, res, view, options) => {
-  // Load notifications
-  if (req.session.user) {
-      res.render(view, {
-        ...options,
-        user: req.session.user,
-        nextUrl: req.url,
-        notifications: req.session.user.notifications
-      });
-      req.session.user.notifications
-        .filter(notification => !notification.persistant)
-        .forEach(notification => notification.remove());
-      req.session.user.save();
-  } else {
-    return res.render(view, {
-      ...options,
-      user: req.session.user,
-      nextUrl: req.url,
-      notifications: []
-    });
-  }
-};
-
-module.exports = render;
\ No newline at end of file
diff --git a/back/views/base.pug b/back/views/base.pug
deleted file mode 100644
index 99efae0a216207cfed851ee8d9310534f58c61ea..0000000000000000000000000000000000000000
--- a/back/views/base.pug
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-html(lang="en")
-  head
-    meta(charset="UTF-8")
-    meta(name="viewport", content="width=device-width, initial-scale=1.0")
-    meta(http-equiv="X-UA-Compatible", content="ie=edge")
-    link(rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" integrity="sha256-9mbkOfVho3ZPXfM7W8sV2SndrGDuh7wuyLjtsWeTI1Q=" crossorigin="anonymous")
-    title RoleGame
-  body
-    script(src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous")
-    script(src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js" integrity="sha256-t8GepnyPmw9t+foMh3mKNvcorqNHamSKtKRxxpUEgFI=" crossorigin="anonymous")
-    script(src="/media/script.js")
-    block navbar
-      if !user
-        form(action="/auth/login", method="post")
-          .ui.pointing.menu
-            a.item(href="/") Home
-            .right.menu
-              .item
-                .ui.input.transparent
-                  input#username(type="text" name="username" placeholder="username")
-                .ui.transparent.input
-                  input#password(type="password" name="password" placeholder="password")
-                .ui.transparent.input
-                  input.ui.button(type="submit" value="Login")
-              a.item(href="/auth/signup") Sign up
-      else
-        form(action="/auth/logout", method="post")
-          .ui.pointing.menu
-            a.item(href="/") Home
-            a.item(href="/characters") My characters
-            .right.menu
-              .item #{user.firstName} #{user.lastName}
-              .item
-                .ui.transparent.input
-                  input.ui.button(type="submit" value="Logout")
-    .ui.grid
-      .three.wide.column
-      .ten.wide.column
-        block main
-      .three.wide.column
-        include notifications.pug