Don't get stuck at the Door.

Don't get stuck at the Door.

Authentication made easy with Auth0

This is my experience building a facial recognition web application to verify students registered for a class.

The Problem

Being my first gig I had limited time to deliver a working application with the core functionality of facial detection and recognition and also build a database system for registering classes and students. How could I save time and deliver? -Auth0 came along <my first time of hearing about the application was from {Avneesh Argarwal} a fellow participant in Hash node Bootcamp Using Auth0 I saved time implementing authentication, validation, and protecting the clients' URLs easily without creating a user model. Okay finally time to start building, my first goal was to build a server, and Express Js proved good for me.

Setting up Auth0 for Express Js.

Setting up Auth0 to interact with my server was relatively easy

Open a new folder and initialize your project with your package manager. I would be using yarn as my package manager.

yarn init

A prompt like this shows up init.png You should have a package.json in your project folder. Now we would be adding the dependencies we would need.

yarn add dotenv ejs express express-openid-connect face-api.js mongoose multer

Running the above command would create a yarn.lock file and node_modules folder in our project folder. With this setup, we can now create the necessary files and folders for our project.

Starting with the server.js in the root folder

const fs = require('fs');
const path = require('path');

const express = require('express');

const mongoose = require('mongoose');
const mongoDB =  process.env.MONGO_URL

const { auth, requiresAuth } = require('express-openid-connect');
const multer = require('multer');

//I'm yet to implement the api as of these blog post 
const faceapi = require("face-api.js")
require('dotenv').config();
const port = process.env.PORT || 5000;

//Schema class from the mongoose module
const Schema = mongoose.Schema;
mongoose.connect(mongoDB,{useNewUrlParser:true, useUnifiedTopology: true});

// Start a server instance with express
const app = express();

// Start a database instance
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));


//Build a Schema for our student collection in our database 
let studentModelSchema = new Schema({
    first_name : {
        type: String
    },
    last_name : {
        type: String
    },
    student_image : {
        data : Buffer,
        contenType: String
    }
})


//Build a Model based one the studentModelSchema 
let studentModel = mongoose.model('studentModel', studentModelSchema )

// set up a storage path with multer to store uploaded image file
let storage = multer.diskStorage({
    destination: (req, file, cb)=>{
        cb(null, 'uploads')
    },
    filename: (req, file, cb) =>{
        cb(null, file.fieldname + '-' + Date.now())
    }
});


let upload = multer({ storage: storage});

// Auth0 
app.use(
    auth({
        authRequired: false,
        auth0Logout: true,
        session:{
            cookie:{
                domain: 'localhost'
            }
        },
        issuerBaseURL: process.env.ISSUER_BASE_URL,
        baseURL: process.env.BASE_URL,
        clientID: process.env.CLIENT_ID,
        secret: process.env.SECRET,
    })
)
// setting up json middleware
app.use(express.json());


//setting up static files
app.use(express.static('public'));
//setting up view's & EJS
app.set('views', './views');
app.set('view engine','ejs');

app.set('trust proxy', true)


// Navigation
app.get('/', function(req, res){
    studentModel.find({}, (err,items)=>{
        if (err){
            console.log(err);
            res.status(500).send("An error occured", err);
        }
        else {
        res.render(req.oidc.isAuthenticated() ? 'home' : 'index', {items:items});
        }
    })
});

//--My AI logic
app.get('/check', (req, res)=>{
    res.render('check');
 })


// app.get('/register',(req, res)=>{
//    res.render('register')
// })

app.get('/profile', requiresAuth(), (req, res)=>{
    res.send(JSON.stringify(req.oidc.user));
})


app.post('/regsiter-student', requiresAuth(), upload.single('student_image'),(req, res, next)=>{
    let obj = {
        first_name : req.body.first_name,
        last_name : req.body.last_name,
        student_image: {
            data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
            contentType : 'image/png'
        }
    }
    studentModel.create(obj, (err, item) =>{
        if(err){
            console.log(err);
        }
        else{
            item.save();
            res.redirect('/');
        }
    });

});

app.post('/check', requiresAuth(), (req, res, next)=>{
    console.log(req.body)
})

app.listen(port, ()=>{
    console.log(`Now listening on port ${port}`)    
});

Next, I set up my index.ejs and home.ejs which from index route in my server.js renders index.ejs when the user is not authenticated but renders home.ejs when the user is authenticated.

Auth0 being a global leader in Identity-as-a-Service(IDaas) is definitely worth it. You can check my project out at psychic-face.herokuapp.com

#hashnode