-
-
Save matiaslopezd/aebb8682d9c4ec3c9c3cd3ffc0edf78d to your computer and use it in GitHub Desktop.
Rate limiting for FeathersJS HTTP (REST API) and Web Sockets connections (Express, Node.js)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict' | |
const bodyParser = require('body-parser') | |
const compress = require('compression') | |
const configuration = require('feathers-configuration') | |
const cors = require('cors') | |
const favicon = require('serve-favicon') | |
const feathers = require('feathers') | |
const hooks = require('feathers-hooks') | |
const limiter = require('limiter').RateLimiter // Generic limiter used for authentication attempts inside web socket connection | |
const middleware = require('./middleware') | |
const path = require('path') | |
const rateLimit = require('express-rate-limit') // Express middleware limiter used for HTTP requests | |
const rest = require('feathers-rest') | |
const serveStatic = require('feathers').static | |
const services = require('./services') | |
const socketio = require('feathers-socketio') | |
const app = feathers() | |
app.configure(configuration(path.join(__dirname, '..'))) | |
const authLimiter = new rateLimit({ | |
windowMs: 15*60*1000, // 15 minutes window | |
delayAfter: 1, // begin slowing down responses after the first request | |
delayMs: 3*1000, // slow down subsequent responses by 3 seconds per request | |
max: 5 // start blocking after 5 requests | |
}) | |
app.use(compress()) | |
.use('/auth/', authLimiter) // limit authentication attempts via REST API | |
.use('/socket.io/', authLimiter) // limit web socket connections | |
.options('*', cors()) | |
.use(cors()) | |
.use(favicon(path.join(app.get('public'), 'favicon.ico'))) | |
.use('/', serveStatic(app.get('public'))) | |
.use(bodyParser.json()) | |
.use(bodyParser.urlencoded({ extended: true })) | |
.configure(hooks()) | |
.configure(rest()) | |
.configure(socketio(io => { | |
io.on('connection', socket => { | |
const socketLimiter = new limiter(1, 3000) // allow 1 authentication attempt every 3 seconds inside current web socket connection | |
socket.on('authenticate', () => { | |
if(!socketLimiter.tryRemoveTokens(1)) { // if exceeded, connection is dropped | |
console.log('Too many socket.io auth attempts from %s, disconnecting.', socket.conn.remoteAddress) | |
socket.send('Too many authentication attempts from you, disconnecting.') | |
socket.disconnect() | |
} | |
}) | |
}) | |
})) | |
.configure(services) | |
.configure(middleware) | |
module.exports = app |
This is the best alternative for distrubution process, shared videsk!
This for generate many request want!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
MongoDB store for limit IP, shared Mongo arquitecture!