@universis/janitor
v1.6.3
Published
Universis api plugin for rate limiting requests
Downloads
164
Maintainers
Readme
@universis/janitor
Universis api plugin for rate limiting requests or slowing down service responses.
Usage
npm i @universis/janitor
RateLimitService
RateLimitService
is a configurable extension of express-rate-limit for limiting service requests.
Register service under application services:
{
"services": [
{
"serviceType": "@universis/janitor#RateLimitService"
}
]
}
and start configuring rate limited endpoints under settings/universis/rateLimit
:
{
"settings": {
"universis": {
"rateLimit": {
"profiles": [
[
"userRateLimitProfile",
{
"windowMs": 300000,
"limit": 50,
"legacyHeaders": true
}
]
],
"paths": [
[
"/users/me",
{
"profile": "userRateLimitProfile"
}
]
]
}
}
}
}
RateLimitService
service configuration consists of a collection of rate limit profiles
that are going to used as options during request validation and a collection of paths
for defining rate limited route paths.
Read more about rate limit configuration at express-rate-limit documentation
Enable rate limit headers over CORS
Each RateLimitService
profile has an option to include a set of headers in the response. This can be done by setting the headers
option to true
in the profile configuration. This operation will add the following headers to the response:
X-RateLimit-Limit
- the maximum number of requests allowed in the current windowX-RateLimit-Remaining
- the number of requests remaining in the current windowX-RateLimit-Reset
- the number of milliseconds remaining until the window resets
Rate limit headers will be available only if the request is made from the same origin. If the request is made from a different origin, the headers will not be included in the response and should be configured to be exposed by CORS.
{
"settings": {
"cors": {
"exposedHeaders": [
"X-Rate-Limit",
"X-Rate-Remaining",
"X-Rate-Reset"
]
}
}
}
SpeedLimitService
SpeedLimitService
is a configurable extension of express-slow-down for slowing down service responses.
Register service under application services:
{
"services": [
{
"serviceType": "@universis/janitor#SpeedLimitService"
}
]
}
and start configuring speed limited endpoints under settings/universis/speedLimit
:
{
"settings": {
"universis": {
"speedLimit": {
"profiles": [
[
"userSpeedLimitProfile",
{
"windowMs": 300000,
"delayAfter": 5,
"delayMs": 500,
"maxDelayMs": 20000,
"headers": true
}
]
],
"paths": [
[
"/users/me",
{
"profile": "userSpeedLimitProfile"
}
]
]
}
}
}
}
SpeedLimitService
configuration consists of a collection of speed limit profiles
that are going to used as options during request validation and a collection of paths
for defining speed limited route paths.
Read more about speed limit configuration at express-slow-down documentation
SpeedLimitService
offers two additional options for delaying response: randomDelayMs
and randomMaxDelayMs
. These options are used for adding random delay to the response. They define the range of random delay in milliseconds.
{
"settings": {
"universis": {
"speedLimit": {
"profiles": [
[
"userSpeedLimitProfile",
{
"windowMs": 120000,
"delayAfter": 5,
"randomDelayMs": [
500,
1000
],
"headers": false
}
]
],
"paths": [
[
"/users/me",
{
"profile": "userSpeedLimitProfile"
}
]
]
}
}
}
}
If randomDelayMs
is set, delayMs
is ignored.
randomMaxDelayMs
is used for setting the maximum random delay. If randomMaxDelayMs
is not set, the maximum delay is set to maxDelayMs
is ignored e.g.
{
"settings": {
"universis": {
"speedLimit": {
"profiles": [
[
"userSpeedLimitProfile",
{
"windowMs": 120000,
"delayAfter": 5,
"delayMs": 500,
"randomMaxDelayMs": [
7000,
12000
],
"headers": false
}
]
],
"paths": [
[
"/users/me",
{
"profile": "userSpeedLimitProfile"
}
]
]
}
}
}
}
Enable speed limit headers over CORS
Each SpeedLimitService
profile has an option to include a set of headers in the response. This can be done by setting the headers
option to true
in the profile configuration. This operation will add the following headers to the response:
X-SlowDown-Limit
- the maximum number of requests allowed in the current windowX-SlowDown-Remaining
- the number of requests remaining in the current windowX-SlowDown-Reset
- the number of milliseconds remaining until the window resets
Speed limit headers will be available only if the request is made from the same origin. If the request is made from a different origin, the headers will not be included in the response and should be configured to be exposed by CORS.
{
"settings": {
"cors": {
"exposedHeaders": [
"X-SlowDown-Limit",
"X-SlowDown-Remaining",
"X-SlowDown-Reset"
]
}
}
}
ScopeAccessConfiguration
ScopeAccessConfiguration
is a configurable application service for limiting access to service endpoints based on user scopes.
Register service under application services:
{
"services": [
{
"serviceType": "@universis/janitor#ScopeAccessConfiguration"
}
]
}
add <config directory>/scope.access.json
and start configuring scope limited endpoints:
[
{
"scope": [
"registrar"
],
"resource": "/api/",
"access": [
"read",
"write"
]
},
{
"scope": [
"students",
"teachers",
"registrar"
],
"resource": "/api/workspaces/locales",
"access": [
"read"
]
}
]
Each configuration element consists of scope
array, resource
string and access
array.
If the user has at least one of the scopes from the scope
array,
and the user has at least one of the access
array, the user will be granted access to the resource.
There are two different access types:
read
- grants access to read the resource (GET, HEAD, OPTIONS)write
- grants access to write the resource (POST, PUT, PATCH, DELETE)
The resource string can be a path or a regular expression e.g. /api/instructors/me/exams/(\d+)/types
validateScope
express.js middleware is available for validating user scope access to the resource:
import { validateScope } from '@universis/janitor';
app.use('/api', passport.authenticate('bearer', {session: false}), validateScope(), (req, res) => {
res.send('Hello World!')
});
A 403 - Access denied due to authorization scopes
error will be thrown if the user does not have access to the resource.
ExtendScopeAccessConfiguration
ExtendScopeAccessConfiguration
is a configurable application service for extending scope access configuration with additional scopes.
Register service under application services:
{
"services": [
{
"serviceType": "@universis/janitor#ExtendScopeAccessConfiguration"
}
]
}
add scopeAccess
section under settings/universis/janitor
configuration and start configuring scope access extension:
{
"settings": {
"universis": {
"janitor": {
"scopeAccess": {
"imports": [
"./custom.scope.access.json"
],
}
}
}
}
}
ExtendScopeAccessConfiguration
service will import additional scope access configuration from the files listed in the imports
array. The file path is relative to the application configuration directory e.g. server/config/
where the main configuration file is located.
The given files should contain an array of scope access configuration elements as described in the ScopeAccessConfiguration
section.
RemoteAddressValidator
RemoteAddressValidator
is a configurable application service for validating access to service endpoints based on remote address provided by OAuth2 token.
Register service under application services:
{
"services": [
{
"serviceType": "@universis/janitor#RemoteAddressValidator"
}
]
}
RemoteAddressValidator
validates the remote address of the request with the remote address provided by the OAuth2 token. If the addresses do not match, a 403 - Access denied due to remote address
error will be thrown. Token remote address is provided by the remoteAddress
claim in the token payload. It can be configured in the OAuth2 server configuration and may have a different name. This name may be configured in the settings/universis/janitor/remoteAddress
configuration e.g.
{
"settings": {
"universis": {
"janitor": {
"remoteAddress": {
"claim": "ipAddress"
}
}
}
}
}
where claim
is the name of the remote address claim in the token payload.
Important Note: If api server is served by a proxy, the remote address may be different from the client address. In this case, the proxy should be configured to forward the client address to the server. This scenario should be configured in application settings under settings/universis/api/
section e.g.
{
"settings": {
"universis": {
"api": {
"proxyAddressForwarding": true
}
}
}
}