All Projects β†’ valentinchelle β†’ nodejs-rest-api-boilerplate

valentinchelle / nodejs-rest-api-boilerplate

Licence: MIT License
A NodeJs boilerplate that implements Google, Facebook and classic Authentication following the best practices. Clear endpoints, easy to use, perfect to start a project quickly. Provides an example front end in ReactJS.

Programming Languages

javascript
184084 projects - #8 most used programming language
CSS
56736 projects
SCSS
7915 projects
HTML
75241 projects

Projects that are alternatives of or similar to nodejs-rest-api-boilerplate

ExpressJS-SocketIO-Boilerplate
πŸ“¦ Simple Express.js & Socket.io Boilerplate
Stars: ✭ 31 (+72.22%)
Mutual labels:  boilerplate-template
docker-django-boilerplate
Minimal boilerplate setup for a Django project with Docker.
Stars: ✭ 41 (+127.78%)
Mutual labels:  boilerplate-template
vuelectro
Bare minimum, simplistic, production ready scaffolding/build tool for developing with Electron and Vue.Js
Stars: ✭ 19 (+5.56%)
Mutual labels:  boilerplate-template
sparrowx
Minimal, SEO-friendly, Jekyll + Netlify CMS Boilerplate.
Stars: ✭ 15 (-16.67%)
Mutual labels:  boilerplate-template
alexa-skill-boilerplate
An easy to use Amazon Alexa Skill Boilerplate for fast skill creation
Stars: ✭ 54 (+200%)
Mutual labels:  boilerplate-template
configurable-app-examples-4x-js
Configurable Application Examples using ApplicationBase
Stars: ✭ 22 (+22.22%)
Mutual labels:  boilerplate-template
ionic-vue-mobile-template-01
Hybrid app template built with vue, ionic and capacitor.
Stars: ✭ 47 (+161.11%)
Mutual labels:  boilerplate-template
starbase
⭐ Production-ready website boilerplate made with webpack 5, modern JS (via Babel 7) & Sass
Stars: ✭ 70 (+288.89%)
Mutual labels:  boilerplate-template
factorio-example-mod
Lightweight modular example mod with various features and compatibilities
Stars: ✭ 15 (-16.67%)
Mutual labels:  boilerplate-template
cli-boilerplates
πŸš€ A Command Line Tool to generate boilerplates with creation of files globally. A tool to help students quick start with single line of code.
Stars: ✭ 27 (+50%)
Mutual labels:  boilerplate-template
ExpressSimpleBoilerPlate
Kerangka project Express JS dengan tambahan ES2015, ESLint, Webpack, Babel, beberapa middleware pengaman, Worker Threads, mock data generator, dan masih banyak lagi.
Stars: ✭ 22 (+22.22%)
Mutual labels:  boilerplate-template
bashew
bash script micro-framework - from small stand-alone script to complex projects with CI/CD and testing
Stars: ✭ 139 (+672.22%)
Mutual labels:  boilerplate-template
webpack-typescript-react
Webpack 5 boilerplate with support of most common loaders and modules (see tags and description)
Stars: ✭ 185 (+927.78%)
Mutual labels:  boilerplate-template
DiscordBot-Template
A boilerplate / template for discord.js bots with 100% coverage of Discord API, command handler, error handler based on https://discordjs.guide/
Stars: ✭ 129 (+616.67%)
Mutual labels:  boilerplate-template
Sims4ScriptingBPProj
Sims 4 Scripting Boilerplate Project
Stars: ✭ 32 (+77.78%)
Mutual labels:  boilerplate-template
awesome-vue-boilerplate
😍 Awesome Vue Boilerplate πŸ₯³ Vue πŸ₯° Vuex, vuex-pathify πŸ€— element-ui 🀲 tailwindcss
Stars: ✭ 60 (+233.33%)
Mutual labels:  boilerplate-template
midway-boilerplate
midway η³»εˆ—θ„šζ‰‹ζžΆδ»“εΊ“
Stars: ✭ 22 (+22.22%)
Mutual labels:  boilerplate-template
bootstrap4-boilerplate
A Bootstrap v4.4.1 boiler plate with sass, concatenation, minification, autoprefixer, Browsersync, hot reloading and sourcemaps all runned by Gulp
Stars: ✭ 19 (+5.56%)
Mutual labels:  boilerplate-template
xd-plugin-boilerplate
A boilerplate for plugins for Adobe XD CC including preconfigured linting, autocompletion and Webpack for bundling
Stars: ✭ 25 (+38.89%)
Mutual labels:  boilerplate-template
beat
Server framework to create fast and lightweight projects
Stars: ✭ 12 (-33.33%)
Mutual labels:  boilerplate-template

Nodejs Boilerplate

A powerful boilerplate for a NodeJS API with Google and Facebook Login.

NodeJs Api Boilerplate

A boilerplate for NodeJs Rest Api. Implements a clean structure, with the best practices for authentication, including OAuth for Google Login and Facebook Login.

You probably know how hard it is to start a node js API, with a well structured and clean code. Especially if you are on a rush for an hackhaton or a school project. I give you here a clean code, that implements what is essential for a new API project : a clean nodejs structure implementing a user system following the best practices.

You can directly plug this API with the client of your choice by calling the different endpoints. I also give details on how to extend this code to adapt it for your project.

This API can be used with any client, here is the client I have developed with ReactJS to interact with this API.

Features

(STILL IN DEVELOMENT) The entity example in this repo is users, but it can be easily applied to articles, messages, ...

  • Secure Authentification with email/password using JWT
  • OAuth 2.0 Authentication via Facebook, Google, GitHub, LinkedIn, Instagram
  • Clean Structure Component Oriented
  • Templates to create your own entities
  • Get Entity
  • List Entity
  • Patch Entity
  • Delete Entity
  • Use Passport
  • Easy-to-use endpoints
  • Middlewares to ensure authentification and permission to access resources.
  • Implemented unit test
  • Posts

Getting Started

Prerequisites

Please make sure that you have:

Cloning the repo

The easiest way to get started is to clone the repository:

# Get the latest snapshot
git clone https://github.com/valentinchelle/nodejs-rest-api-boilerplate.git myproject

# Change directory
cd myproject

# Install NPM dependencies
npm install

# Then simply start your app
npm start

Configuration of the environment

To use all the functionnalities, you will need to set the environment variables.

Firstly, add a file named .env at the root of the folder (same level as index.js), copy paste the following template and save it. You can change the value of JWT_SECRET to something else to make it more secure.

GOOGLE_CLIENT_ID=googleclientid.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=googleclientsecret
FACEBOOK_CLIENT_ID=fbclientid
FACEBOOK_CLIENT_SECRET=fbclientsecret
MONGO_URI=mongodb+srv://{user}:{password}@cluster0-ukuem.mongodb.net/test?retryWrites=true&w=majority
JWT_SECRET=randomString123

The three next steps will help you filling the other value of the .env file.

Setup : MongoDB

  • Create a new account on https://cloud.mongodb.com/ and choose the free plan
  • On the homepage, click on _Connect > Connect your application > _
  • Copy the Connection String, replace by your actual password, and paste in the .env as MONGO_URI

Setup : OAuth for Facebook Login

  • Go on https://developers.facebook.com/apps and create a new app
  • Add Facebook Login to its products
  • In the settings of the Facebook Login Product
  • If your servers runs locally, make sure the facebook app is in development mode
  • If not, add url-of-server:port/api/auth/facebook/callback in the field Valid OAuth Redirect URIs
  • Grab your Client ID and Client Secret in Settings>Basic
  • Fill the .env at the root of the server with these credentials

Setup : OAuth for Google Login

  • Go on https://console.cloud.google.com/ and create a new app
  • Add Credentials > OAuth client ID
  • In Authorized JavaScript origins, enter http://server:port ( for me http://127.0.0.1:5000)
  • In Authorized redirect URIs, enter http://server:5000/api/auth/google/callback ( for me http://localhost:5000/api/auth/google/callback)
  • Grab your Client ID and Client Secret on the same page
  • Fill the .env at the root of the server with these credentials

Structure

The structure of this boilerplate follows the guideines of the component oriented structure : Each component corresponds to a folder, and follows an Model Controller Middlewares sub structure :

  • models for the database entities ( like users ). It is where the schema, and the communication with the table are defined (like UserModelfindById).
  • controllers/ for the actions on the models, that call the models actions ( like the management of the list of the users).
  • middlewares/ intermediaries between the request and the response. Usually uses and modifies the request body parameters.
  • routes.js for the definition of the endpoints for each actions of the controllers. Defines also what are the middleware used for the routes.

The global logic for an app calling this rest API :

  1. The client will call an API route ( like url/api/users/modifyuser )
  2. The router makes the request pass through middlewares ( like isConnected()) to validate the request
  3. The router feeds the controller by calling one of its action ( like modifyUser()).
  4. The controller action access the model ( the database ) to modify/access a record in the table.
  5. The controller ends up by returning a response

Api Endpoints

Endpoints for the authentification

Endpoint Body Request Fields Description
POST /api/auth/login {email : "", password:""} Login the user
POST /api/auth/refresh {refresh_token: ""} Generate a new Json Web Token
POST /api/auth/register {email : "", name:"", password :"", password2:""} Creates a new user.
GET /api/auth/google Entry point for the Google Oauth
GET /api/auth/facebook Entry point for the Facebook Oauth

Endpoints for Entities ( Users )

This is the usual API endpoints for a given entity ( here the users ):

Endpoint Token Needed Body Request Description
GET /api/users/ yes Returns the list of the users
GET /api/users/:id yes Returns info about the user
PATCH /api/users/:id yes {name : "John"} Updates the user with the body request
DELETE /api/users/:id yes Deletes the user. ADMIN ONLY

Routes Middlewares

The middlewares are used to validate a request. In this boilerplate, it is mainly used here to make sure the user has the permission to access the route. Here is the list of the different middleware and where they are implemented.

It is then very easy to use, as shown in this example :

const AuthMiddleware = require("../auth/middlewares/auth.middleware");
const PermissionsMiddleware = require("../users/middlewares/permissions.middlewares");
router.delete("/:userId", [
  AuthMiddleware.validJWTNeeded,
  PermissionsMiddleware.minimumPermissionLevelRequired(ADMIN),
  UsersController.removeById
]);

Useful

Name Path Description
validJWTNeeded auth/middlewares/auth Ensures the user is logged with a valid JWT
onlySameUserOrAdminCanDoThisAction users/middlewares/permissions For actions like editing profile
minimumPermissionLevelRequired users/middlewares/permissions Ensures the user has the permission
sameUserCantDoThisAction users/middlewares/permissions Ensures the user can't do the action

Specific

Name Path Description
onlySameUserOrAdminCanDoThisAction users/middlewares/permissions For actions like editing profile
verifyRefreshBodyField auth/middlewares/auth Ensures the request contains a refresh token
validRefreshNeeded auth/middlewares/auth Ensures the refresh token is valid
JwtNeeded auth/middlewares/auth Ensures the contains a JWT token (not valid)

Understanding the login logic

What is a JWT ?

Our authentifcation system relies on a JWT, JSON Web Tokens. The idea is to encode the user information, and to load all the communication between the server and the frontend with this token. This token has usually an expire date.

A simple overview would be :

// ----------- SERVER SIDE -----------
const User = { name: "John", age: 21}
const jwt = encode(User, expireIn = 60 ); // will expire in 60 seconds
send_jwt_to_client();
// ----------- CLIENT SIDE -----------
const jwt = receive_jwt_from_server();
const User = decode(jwt);
>>> console.log(User)
{
  "name": "John",
  "age" : 21,
  "iat": 1516239022
}

The authentication steps

Authenticate a user

Here is the different request between the server and the font end to handle the authentication.

  1. The user enters its credentials on the client
  2. The client sends the credentials to the server
  3. The server compares the credentials with the database
  4. The server sends back to the client a jwt token ( containing information about the user ) and a refresh token
  5. The client extracts the token, sets the Authorization Headers of the next requests to Bearer + token_value

Give Access

Now that the client registered the jwt tokenand the refresh token, let's say the user tries to access a protected resource

  1. the client sends a request to the server, with the jwt token in Authorization headers
  2. the server checks the validity of the jwt token, and if it is valid, returns a result

Refresh the token

The subititly is that for the system to be secure enough, the jwt token is encrypted with a limited lifetime. If the client detects that the jwt token is expired, it needs a new one. Here is the process :

  1. The client sends the expired jwt token along with the refresh token
  2. The server checks the validity of the refresh token, and generates a new jwt token
  3. The server sends back the same refresh token and the new jwt token

Step 1 : Login with credentials

The first step in the login process, is for a registered user to send its email/passsword. Endpoint : endpoint:3600/auth Body :

{
  "email": "[email protected]",
  "password": "secret"
}

If the login credentials are right, the response should be like:

{
  "accessToken": "eyJhbGcidOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI1ZTIzNjRlZDQ4NDE2YzY2ZjYwMGIwYjgiLCJlbWFpbCI6InZhbGVudGluLmNoZWxsZTNAZ21haWwuY29tIiwicGVybWlzc2lvbkxldmVsIjoxLCJwcm92aWRlciI6ImVtYWlsIiwibmFtZSI6InVuZGVmaW5lZCB1bmRlZmluZWQiLCJyZWZyZXNoS2V5IjoiRUlVUk12NENQKytOZitzSHRnZThFZz09IiwiaWF0IjoxNTc5Mzc5NTY1fQ.jBIa5DNI0ObjVW7i3qF68XguKxuw_4lLmr-5S15rOp4",
  "refreshToken": "RFZJZE5YRWldTS3B2bWtUUlByaVZUeVJNTVFyYko5Sm80OUsycWtYUU9PYlFuQURCYkh4K202YWxnd2IybmFiRkQ0TWl2TElQemJKeGUrQ3FpdXVmR3c9PQ=="
}

The access token is the famous json web token. It is a stateless string that will allow someone to stay logged everytime they provide this token to the server.

Step 2 : Stay logged with the JWT

In order to make your users stay logged on your app, you have to provide the jwt for each request. To do that, on the client side, grab the accessToken from the previous request, prefix it with Bearer and add it to the request headers under Authorization. This will be required for every route with the middleware ValidationMiddleware.validJWTNeeded like :

  app.patch("/users/:userId", [
    ValidationMiddleware.validJWTNeeded,
    PermissionMiddleware.minimumPermissionLevelRequired(FREE),
    PermissionMiddleware.onlySameUserOrAdminCanDoThisAction,
    UsersController.patchById
  ]);

Security Concerns

At the end of the OAuth, the jwt is sent via a get request to the client, so it could possibly appear in the history/logs of the server...

References

Encrypting the passwords : https://github.com/goldbergyoni/nodebestpractices/tree/security-best-practices-section#-68-avoid-using-the-nodejs-crypto-library-for-passwords-use-bcrypt

Credits

This project has been largely inspired by the following work : https://github.com/gothinkster/node-express-realworld-example-app/blob/master/routes/api/articles.js

https://github.com/makinhs/rest-api-tutorial

Visit www.toptal.com/blog and subscribe to our newsletter to read great posts

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].