loading...

ArangoDB : The new Graal ? Part 2

solisoft profile image BONNAURE Olivier ・2 min read

In part1 I just show you a very basic foxx service. In this part 2 I'll show you how to create a service to manage authentifications using JWT.

Let's start creating a new service. First we need to define what we will need for this service.

'use strict';
const db = require('@arangodb').db;
const joi = require('joi');
const createRouter = require('@arangodb/foxx/router');
const sessionsMiddleware = require('@arangodb/foxx/sessions');
const jwtStorage = require('@arangodb/foxx/sessions/storages/jwt');
const createAuth = require('@arangodb/foxx/auth');
const auth = createAuth();
const router = createRouter();

Ok so we will need :

  • db object for accessing database
  • joi for all validations stuff
  • sessionsMiddleware to manage sessions (see below)
  • jwtStorage to be able to use JWT
  • router which is the router
  • auth auth tool (create & verify methods)

Now it's time to create the session

const sessions = sessionsMiddleware({
  storage: jwtStorage({ secret: "Secret", ttl: 60 * 60 * 24 * 7 }),
  ttl: 60 * 60 * 24 * 7, // one week in seconds
  transport: 'header'
});

Ok easy, we just define the storage, ttl & transport.

Our service need to be linked to this sessions

module.context.use(sessions);
module.context.use(router);

Our service is linked now to our sessions & router

It's time to create endpoints.
Let's start with the signup one.

router.post('/signup', function (req, res) {
  const user = req.body; // get the form defined in the body section below

  try {
    // Create an authentication hash
    user.authData = auth.create(user.password);

    // Delete plain password data
    delete user.password;
    delete user.password_confirmation;

    // Validate user (for demo purpose)
    user.a = true
    const meta = db.users.save(user);
    Object.assign(user, meta); // assign _key, _id to user
  } catch (e) {
    res.throw('bad request', 'Username already taken', e);
  }
  // Set the session uid
  req.session.uid = user._key;
  res.send({success: true});
})
.body(joi.object({
  "fn": joi.string().required(),
  "ln": joi.string().required(),
  "username": joi.string().required(),
  "password": joi.string().min(8).max(32).required(),
  "password_confirmation": joi.string().required(),
}), 'Credentials')
.description('Creates a new user and logs them in.');

Here the login endpoint

router.post('/login', function (req, res) {
  // This may return a user object or null
  const user = db.users.firstExample({
    username: req.body.username,
    a: true
  });
  const valid = auth.verify(
    user ? user.authData : {},
    req.body.password
  );
  // Log the user in
  if(valid) {
    req.session.uid = user._key;
  }
  // Corrs
  res.setHeader("Access-Control-Expose-Headers", "X-Session-Id");
  res.send({success: valid, uid: req.session});
})
.body(joi.object({
  username: joi.string().required(),
  password: joi.string().required()
}).required(), 'Credentials')
.description('Logs a registered user in.');

And finally, here is the logout endpoint

router.post('/logout', function (req, res) {
  if (req.session.uid) {
    req.session.uid = null;
  }
  res.send({success: true});
})
.description('Logs the current user out.');

You can find the complete code in this gist

ArangoDB will provide you a nice swagger documentation to check that everything is ok.

swagger

On next part, I'll show you a complete CRUD for managing your collections.

Discussion

pic
Editor guide