Node JS

Chapter 6 : REST TO API AUTHENTICATION

REST TO API AUTHENTICATION

  1. Authentication Introduction

  2. Authorization Introduction

  3. Types of Authentications

  4. Hashing the password

  5. Setting log/sign - in routes

  6. Setting JWT 

  7. Creating Authorization middleware 

1. Authentication Introduction

What is Authentication ?

Authentication is the process of verifying a user’s identification through the acquisition of credentials and using those credentials to confirm the user’s identity. 

2. Authorization Introduction

What is Authorization?

Authorization is the process of allowing authenticated users access to resources by determining whether they have system access permissions. By giving or denying specific licenses to an authenticated user, authorization enables you to control access privileges.

3. Types of Authentications

What are the types of Authentications ?

  • API Keys Authentication

  • Basic Authentication

  • Bearer Authentication

  • OAuth 2.0

  • OpenID Connect Discovery

  • Cookie Authentication

3. Types of Authentications

API Keys Authentication

Some APIs use API keys for authorization. An API key is a token that a client provides when making API calls. 

The key can be sent in the query string :

GET /something?api_key=abcdef12345

As a request header

GET /something HTTP/1.1
X-API-Key: abcdef12345

As a cookie

GET /something HTTP/1.1
Cookie: X-API-KEY=abcdef12345

3. Types of Authentications

Basic Authentication

Basic authentication is a simple authentication scheme built into the HTTP protocol. The client sends HTTP requests with the Authorization header that contains the word Basic word followed by a space and a base64-encoded string username:password.

Authorization: Basic ZGVtbzpwQDU1dzByZA==

3. Types of Authentications

Bearer authentication

Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens.  The bearer token is a cryptic string, usually generated by the server in response to a login request. The client must send this token in the Authorization header when making requests to protected resources:

Authorization: Bearer <token>

4. Hashing the password

Why hashing passwords

For security reasons, you may want to store passwords in hashed form. This guards against the possibility that someone who gains unauthorized access to the database can retrieve the passwords of every user in the system. Hashing performs a one-way transformation on a password, turning the password into another String, called the hashed password.

4. Hashing the password

How to hash passwords in Node?

> npm i bcrypt
userSchema.pre("save", async function (next) {
    try {
        if (this.isModified("password")) 
          this.password = await bcrypt.hash(this.password, 10);
        next();
    } catch (e) {
        next(e);
    }
});
const bcrypt = require("bcrypt");

5. Setting sign - in/up routes

Sign up route

app.post("/signup", async (req, res) => {
    const { email, username, first_Name, last_Name, password } = req.body;
    try {
        const user = await User.create({ email, username, first_Name, last_Name, password });
        res.json(user); // create auth token
    } catch (e) {
        res.json({ error: e.message });
    }
});

5. Setting sign - in/up routes

Sign in route (log in)

app.post("/login", async (req, res) => {
    const { username, password } = req.body;
    try {
        const user = await User.findOne({ username });
        if (!user) throw new Error("Couldn't find a user using this username");
        if (!(await user.comparePasswords(password))) throw new Error("Wrong password");
        res.json(user); // create auth token
    } catch (e) {
        res.json({ error: e.message });
    }
});

5. Setting sign - in/up routes

Password comparation Middleware

userSchema.methods.comparePasswords = async function (candidatePass, next) {
    try {
        return await bcrypt.compare(candidatePass, this.password);
    } catch (e) {
        next(e);
    }
};

6. Setting JWT

What is JWT ?

JSON Web Token is a proposed Internet standard for creating data with optional signature and/or optional encryption whose payload holds JSON that asserts some number of claims. The tokens are signed either using a private secret or a public/private key.

6. Setting JWT

How to implement  JWT?

> npm i jsonwebtoken
userSchema.methods.insertToken = function (token) {
    let user = this.toObject();
    delete user.password;
    user.token = jwt.sign(
      { id: user._id, username: user.username }, 
      process.env.SECRET_KEY, {
        	expiresIn: "100h",
    	});
    return user;
};
const jwt = require("jsonwebtoken");

6. Setting JWT

Use Token insertion

res.json(user.insertToken());

Replace in Sing in/up

res.json(user);

BY

7. Creating Authorization middleware 

Check user is logged in

async function isLoggedin(req, res, next) {
    if (!req.headers.authorization) return res.status(400).send("No authorization's token");
    req.token = req.headers.authorization.split(" ")[1];
    try {
        let decoded = jwt.verify(req.token, process.env.SECRET_KEY);
        req.user = await User.findById(decoded.id).select("-password");
        console.log(req.user);
        next();
    } catch (e) {
        switch (e.constructor) {
            case jwt.TokenExpiredError:
                return res.send("Expired Token");
            case jwt.JsonWebTokenError:
                return res.send("Invalid Token");
        }
    }
}

7. Creating Authorization middleware 

Check user is an Admin

async function isAdmin(req, res, next) {
    if (!req.user) return res.status(400).send("No authorization's token");
    if (!req.user.isAdmin) return res.status(400).send("user is not an Admin");
    next();
}

REST TO API AUTHENTICATION

Ends

Node js Chapter 6 Authentication

By Youcef Madadi

Node js Chapter 6 Authentication

  • 283