Giter Site home page Giter Site logo

aichbauer / express-rest-api-boilerplate Goto Github PK

View Code? Open in Web Editor NEW
481.0 481.0 190.0 164 KB

Express REST API with JWT Authentication and support for sqlite, mysql, and postgresql

License: MIT License

JavaScript 100.00%
authentication ava boilerplate express jwt mysql nodejs postgresql sqlite

express-rest-api-boilerplate's People

Contributors

ace3 avatar aichbauer avatar geofrocker avatar jpeer264 avatar kewlashu avatar leothorp avatar manhyuk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

express-rest-api-boilerplate's Issues

Wrap your tests is a `describe` block...

...otherwise each test block runs in parallel within the test file. This can cause a race condition leading to some test cases failing.

describe('Test Description', () => {
    test()
    test()
})

Error: Cannot find module 'core-js/modules/es6.object.define-property'

I've just encountered a problem while yarn start command. Google searches says it's related with babel but solutions they offered didn't work.

Ubuntu 19.04
latest npm and node

whole log:

> [email protected] dev /home/srht/Codes/birebir/bb-server_2
> cross-env NODE_ENV=development node ./api/api.js

internal/modules/cjs/loader.js:638
    throw err;
    ^

Error: Cannot find module 'core-js/modules/es6.object.define-property'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
    at Function.Module._load (internal/modules/cjs/loader.js:562:25)
    at Module.require (internal/modules/cjs/loader.js:690:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/home/srht/Codes/birebir/bb-server_2/node_modules/express-routes-mapper/lib/index.js:5:1)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] dev: `cross-env NODE_ENV=development node ./api/api.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/srht/.npm/_logs/2019-06-21T10_32_25_035Z-debug.log
[nodemon] app crashed - waiting for file changes before starting...

Adding Socket Listener on same port.

Hi,

I was wondering to add socket.io on the same port, something like this.

const app = require('./index.js');
const port = process.env.PORT;

// Server
let server = app.listen(port, () => {
  console.log(`Listening TCP on: http://localhost:${port}`);
});

let io     = require('socket.io')(server);
console.log(` WS on: http://localhost:${port}`);
io.on('connection', (socket) => {
  console.log('IO user connected');
});

I need some ideas to create routes for socket IO. I am not able to figure out that routing mechanism.

Can't do associations in Model file

I'm new to this project (and sequelize and postgres) so this may be a dumb question, but I'm having trouble doing my model associations in the model file itself. If I do something like (this is an example, not sure it would happen under this circumstance) -
`
const Sequelize = require('sequelize');
const sequelize = require('../../../../config/database');
const User = require('../users/User');
const DataTypes = Sequelize.DataTypes;

const Manager = sequelize.define('Manager', {
license_num: DataTypes.STRING,
reputation: DataTypes.FLOAT,
});
Manager.belongsTo(User);
module.exports = Manager;
`
I get an error to the effect that Manager.belongsTo is being called with something that is not a subclass of Model. If I log it out, I get User = {}. It seems to have an issue with the load order possibly? ie The sequelize connection has not established that the User is not a sequelize object.

If I do a function that holds all my associations in a separate file and run them in api.js, it works fine, but it seems cleaner to do them in the model file itself. Any ideas?

NPM i fails on default package.json

In the default package.json included there is a incorrect version for sequelize.

Current:
"sequelize": "^6.0.0"

Issue: This fails to install since NPM cannot find version 6.0.0. To resolve change the version to the below:
"sequelize": "^6.0.0-beta.5"

Feat: refresh token for jwt

Currently the access token is valid as long as the expiration time is set to and than the user has to re-authenticate. This means if the token is valid for a long time, and the token gets compromised by a third party this means that this third party can have access as long as they want to a service, unless we change our secret on for the jwt for our service. There are other ways like: blacklisting compromised tokens, but this is only possible if we can check that it is not the real user, that is using this token to get access to our service. So we need to be sure, which is only possible if a user tells us explicitly that this is not him, or we try to create a pattern a for a user, e.g. storing information on IP, Location, OS, browserinfo, etc. but this would need additional db request every time a user makes a request.

If we used a refresh token, we would send a access token, and a refresh token to the client (maybe as a http only cookie?) and store a relation for the refresh token and a user that uses this refresh token. E.g. in the database or in another mutable store on the server.

EDIT: Do not think that http only cookies, or cookies should be set as default. There could be problems with mobile apps when this serves as backend. This could be a opt-in or maybe we could check if a mobile app or a web browser accesses the app, but this is not a problem that this project solves rather a problem a individual user has to decide.

The access token expires fast e.g 1 minute, 7 minutes, or longer (depending on the service, security risks, etc). This means there is no additional db call within the time this token is valid, as soon as it expires, we check the refresh token and check if its the same that we stored for our user. if so create a new jwt and refresh token and send it to a user, if not clear the refresh token in the store and the user has to re-authenticate e.g. login with credentials or similar.

something similar like

// this is just pseudo code, e.g. accessToken === valid
const auth = (req, res, next) => {
  const accessToken = req.cookies.accessToken;
  const refreshToken = req.cookies.refreshToken;

  if(accessToken && refreshToken) {
    if(accessToken === valid) {
      return next();
    }
    if(refreshToken === valid) {
      const {
        accessToken,
        refreshToken,
      } = createNewToken(); // clear old refreshToken for user, save new refreshToken

       res.cookie('accessToken', accessToken, cookieOptions);
       res.cookie('refreshToken', refreshToken, cookieOptions);

      return next();
    }
  }

  // possible attack
  return res.status(401).json({ msg: 'Unauthorized' });
};

Routes not working

I have configured MySql but routes are not working. Getting 'Cannot GET /route name ' error on every route. What am I missing in the configuration installation?

How to create a build script

Hi,

I want to deploy a build of this to my production. Can someone suggest a method to build a distrib of this?

TIA

JWTService.verify is not a function

Hi. It's again me : DDD
Am..idk. I don't touch this files. But when i want to /get : /private/users
I have a error : JWTService.verify is not a function

Ofc i save my bearer token, and i test valid this token in /public/validate.

I test this in POSTMAN, and this is doesn't work.
Thanks for help .

Not compatible with Node 10

Hi,

I am trying to build this for node 10. But I get the following error.


yarn add v1.19.2
[1/4] 🔍  Resolving packages...
info There appears to be trouble with your network connection. Retrying...
[2/4] 🚚  Fetching packages...
error [email protected]: The engine "node" is incompatible with this module. Expected version ">=4 <=9". Got "10.17.0"
error Found incompatible module.

Can you please help?

Rendering views with data

Hi, Your boilerplate has been incredibly helpful in learning about how express and mvc works. Could you give me some pointers as to how I would render data to pug views using the boilerplate? Are the controllers going to pass on the data to the renderer?

npm start error

I am getting below error with npm start

> [email protected] start D:\express-rest-api-boilerplate-master
> npm run nodemon


> [email protected] nodemon D:\express-rest-api-boilerplate-master
> nodemon --exec npm run dev

[nodemon] 1.19.1
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `npm run dev`

> [email protected] dev D:\express-rest-api-boilerplate-master
> cross-env NODE_ENV=development node ./api/api.js

module.js:487
    throw err;
    ^

Error: Cannot find module 'core-js/modules/es6.object.define-property'
    at Function.Module._resolveFilename (module.js:485:15)
    at Function.Module._load (module.js:437:25)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (D:\express-rest-api-boilerplate-master\node_modules\express-routes-mapper\lib\index.js:5:1)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] dev: `cross-env NODE_ENV=development node ./api/api.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\***\AppData\Roaming\npm-cache\_logs\2019-06-26T00_32_12_101Z-debug.log
[nodemon] app crashed - waiting for file changes before starting...

I am runnung node 8 on windows 10.

Please help.
Thanks in advance

Feat: JWT_SECRET by default and enforcing a strong secret in production

We should let the user know if they use a unsafe JWT_SECRET when they are not using production. jsonwebtoken uses HS256 as algorithmen, I read an article that it is possible to actually brute force the secret of a HS256 algorithm when using a "bad" secret. Actually one should use a 256 bit secret. which is the equivalent of 32 charcaters, since 1 char is 8 bit.

It would be better to actually throw when using NODE_ENV=production and not using a strong secret. Also it would be good to let the user know if they are using a "good" secret.

I would recommend something similar to:

// api/services/production.service.js
const productionService = () => {
  if (
    process.env.NODE_ENV
    // we have to choose a strong secret
    && process.env.JWT_SECRET
    && process.env.DB_NAME
    && process.env.DB_USER
    && process.env.DB_USER
    && process.env.DB_PASS
  ) {
    if (process.env.JWT_SECRET.length <= 31) {
      throw new Error('Not safe for production: JWT_SECRET should be at least 256 bit, e.g. 32 characters long');
    }

    return true;
  }

  throw new Error('Not safe for production: you forgot to set one or more environment variables');
};

module.exports = productionService;
// api/services/auth.service.js
const jwt = require('jsonwebtoken');

const productionService = require('./production.service');

const safeSecret = process.env.JWT_SECRET ? process.env.JWT_SECRET.length >= 32 : true;

const secret = () => {
  if (
    (
        safeSecret
        && process.env.JWT_SECRET
    )
    || 
    (
      process.env.NODE_ENV === 'production'
      && productionService()
    )
  ) {
    return process.env.JWT_SECRET;
  }

  if (
        !safeSecret
        && process.env.JWT_SECRET
    ) {
    console.error('\n\n\nYou are using a JWT_SECRET that would not be safe for production. Keep in mind that your secret should be at least 256 bit, e.g. 32 characters long.\n\n\n')
    return process.env.JWT_SECRET;
  }

  return 'secret';
};

const mySecret = secret();

const authService = () => {
  const issue = (payload) => jwt.sign(payload, mySecret, { expiresIn: 10800 });
  const verify = (token, cb) => jwt.verify(token, mySecret, {}, cb);

  return {
    issue,
    verify,
  };
};

module.exports = authService;

NODE_ENV is undefined

Looks like the process.env.NODE_ENV is being set to undefined.

The cross-env doesn't seem to function properly from the scripts.

I'm trying to set the flag as development, but getting undefined, and an error as below -

only development, staging, test and production are valid NODE_ENV variables but undefined is specified

Kindly suggest solution.

Test: switch to jest

As AVA is super slow when used with babel we should switch to jest as our test runner.

Problem with routes

Hi! I'm triying run the project but I have this error
/express-rest-api-boilerplate/api/api.js:26
const mappedOpenRoutes = mapRoutes(config.publicRoutes, 'api/controllers/');
^

TypeError: mapRoutes is not a function

Thanks

current architecture does not generate migration files

first off, thanks for this boilerplate! helped me in many ways.

using sequelize-cli automatically generates models and migration files. since this boilerplate doesn't make use of sequelize-cli, models and their associations need to be defined manually.

i'm considering integrating sequelize-cli myself, but i don't know how much it will mess with the file dependencies using the current architecture?

are there any plans to upgrade to using sequelize-cli?

How can i use your API in front POST?

Hi guys. Thank you very much for good job. It's very good API.
But i'm a noob in FrontEnd and can't understand how i can use your API.
I mean.
First question : What different between /public and /private?
Second : i have code in my VUE client

import axios from 'axios';
export default {
  data () {
    return {
        form: {
        username: '',
        password: '',
      },
    }
  },
 methods: {
    onSubmit (evt) {
      evt.preventDefault()
      // this.$router.push('/home')
    axios.post(`http://localhost:3003/api/login`, this.form)
    .then(response => {
      // JSON responses are automatically parsed.
      this.form = response.data
      sessionStorage.setItem('token',response.data.token);
      this.$router.push('/home')
    })
    .catch(e => {
      console.log(e)
    })
    }
  }

And i have troubles only with Login. Auth service work good.
What i have to do for use your api? Can't understand.
Sry for my noobs qust. And thank you for listening.
P.S. and ofc. sry for bad eng, from Russia.

How define belongsToMany association for users?

Hi,

I tried to make two models of User(exist in this repo) and Team(new).
I added following in User model.
const Team = require("./Team");
Team.memberAssociation = User.belongsToMany(Team, { through: "member" });

How do I make this relationship in Team model, and how to add a user to Team in UserController.js in a method like register?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.