aichbauer / express-rest-api-boilerplate Goto Github PK
View Code? Open in Web Editor NEWExpress REST API with JWT Authentication and support for sqlite, mysql, and postgresql
License: MIT License
Express REST API with JWT Authentication and support for sqlite, mysql, and postgresql
License: MIT License
...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()
})
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...
If we use passport we could implement different authentication strategies with ease.
[email protected] drop-sqlite-db
rm ./db/database.sqlite
'rm' is not recognized as an internal or external command,
operable program or batch file.
the table for a new defined model is not getting created the way it is generated for User model
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.
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?
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"
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' });
};
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?
Hi,
I want to deploy a build of this to my production. Can someone suggest a method to build a distrib of this?
TIA
How to use document generator npm ? like https://www.npmjs.com/package/api-doc-generator
because we have a diffrent format of the route.js
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 .
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?
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?
found shelljs/shx for cross platform commands to use in package.json
. Maybe in combination with cross-env. So the npm scripts will look more readable.
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
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;
How to add file upload functionality using multer middleware in this boilerplate.
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.
As AVA
is super slow when used with babel
we should switch to jest
as our test runner.
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
hi
there is a typo in the link you provided: $ git clone https://github.com/aichbauer/express-resr-api-boilerplate.git where express-resr should be express-rest I guess!
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?
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.
@ace3 / @aichbauer can you help me how can I setup the 1:1, 1:N relations in this setup. I am not able to do it and getting error. Please help.
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?
How to create an association in this structure?
Hi,
How would I go about not having the DB reset upon starting the server? cheers
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.