Node.js
This module is made for web servers using Node.js.
It can be imported using both CommonJS or ES module syntaxes.
This documentation is for version
2.x.x
- If you are running with version
1.x.x
of the Node.js module, please follow this documentation.- If you are upgrading your integration from version
1.x.x
to version2.x.x
, please follow this guide to ensure a successful migration.
Supported versions
DataDome supports Node.js versions until they reach their End of life date.
You can find the maintenance schedule of each Node.js version in this GitHub repository.
This module is compatible with Node.js versions 18 and above.
Prerequisites
- The server-side key available in your DataDome dashboard
Available modules
- @datadome/module-express for an integration with the Express framework
- @datadome/module-http for an integration with the built-in HTTP module from Node.js
Integration with Express framework
Compatibility
- Express >= 4.x
Installation
The module can be installed as an npm package:
npm install @datadome/module-express
Usage
const { DatadomeExpress } = require('@datadome/module-express');
const express = require('express');
const app = express();
const datadomeClient = new DatadomeExpress('Some Key');
app.use(datadomeClient.middleware());
app.get('/', function (req, res) {
res.send('Hello World');
});
app.listen(3000);
import { DatadomeExpress } from '@datadome/module-express';
import express from 'express';
const app = express();
const datadomeClient = new DatadomeExpress('Some Key');
app.use(datadomeClient.middleware());
app.get('/', function (req, res) {
res.send('Hello World');
});
app.listen(3000);
Integration with built-in HTTP module from Node.js
Installation
The module can be installed as an npm package:
npm install @datadome/module-http
Usage
const { DatadomeHttp } = require('@datadome/module-http');
const http = require('http');
const datadomeClient = new DatadomeHttp('Some Key');
const server = http.createServer(async (req, res) => {
const { result, error } = await datadomeClient.handleRequest(req, res);
if (result === 'ALLOW') {
console.log('Request allowed');
if (error) {
console.error(error);
}
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
} else {
console.log('Request challenged');
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
import { DatadomeHttp } from '@datadome/module-http';
import http from 'http';
const datadomeClient = new DatadomeHttp('Some Key');
const server = http.createServer(async (req, res) => {
const { result, error } = await datadomeClient.handleRequest(req, res);
if (result === 'ALLOW') {
console.log('Request allowed');
if (error) {
console.error(error);
}
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
} else {
console.log('Request challenged');
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Configuration
The module can be used with minimal configuration including only the server-side key:
const datadomeClient = new DatadomeExpress('Some Key');
const datadomeClient = new DatadomeHttp('Some Key');
Settings
Option name | Description | Default value |
---|---|---|
enableGraphQLSupport | Enable the support of GraphQL requests. | false |
endpointHost | Host of the Protection API. | 'api.datadome.co' |
logger | The Logger instance to use in the module. | console |
timeout | Timeout in milliseconds, after which the request will be allowed. | 150 |
urlPatternInclusion | Regex to match to process the request with the Protection API. If null , all requests that don't match urlPatternExclusion will be processed. | null |
urlPatternExclusion | Regex to match to exclude requests from being processed with the Protection API. If null , all requests will be processed. | \.(avi|flv|mka|mkv|mov|mp4|mpeg|mpg|mp3|flac|ogg|ogm|opus|wav|webm|webp|bmp|gif|ico|jpeg|jpg|png|svg|svgz|swf|eot|otf|ttf|woff|woff2|css|less|js|map|json|avif|xml|gz|zip)$ |
Here is an example of configuration with default values that you can modify according to your needs:
const datadomeClient = new DatadomeExpress('Some Key', {
timeout: 150,
urlPatternInclusion: null,
urlPatternExclusion: /\.(avi|flv|mka|mkv|mov|mp4|mpeg|mpg|mp3|flac|ogg|ogm|opus|wav|webm|webp|bmp|gif|ico|jpeg|jpg|png|svg|svgz|swf|eot|otf|ttf|woff|woff2|css|less|js|map|json|avif|xml|gz|zip)$/i,
endpointHost: 'api.datadome.co',
});
const datadomeClient = new DatadomeHttp('Some Key', {
timeout: 150,
urlPatternInclusion: null,
urlPatternExclusion: /\.(avi|flv|mka|mkv|mov|mp4|mpeg|mpg|mp3|flac|ogg|ogm|opus|wav|webm|webp|bmp|gif|ico|jpeg|jpg|png|svg|svgz|swf|eot|otf|ttf|woff|woff2|css|less|js|map|json|avif|xml|gz|zip)$/i,
endpointHost: 'api.datadome.co',
});
Advanced usage
Logging enriched headers
You can log the values of DataDome Enriched Headers after the handleRequest
method has returned a result:
const { DatadomeExpress } = require('@datadome/module-express');
const express = require('express');
const app = express();
const datadomeClient = new DatadomeExpress('Some Key');
app.use(async (req, res, next) => {
const { result, enrichedHeaders, error } = await datadomeClient.handleRequest(req, res);
if (enrichedHeaders) {
for (const [key, value] of Object.entries(enrichedHeaders)) {
console.log(`Enriched header ${key}: ${value}`);
}
}
if (result === 'ALLOW') {
console.log('Request allowed');
if (error) {
console.error(error);
}
next();
} else {
console.log('Request challenged');
}
});
app.get('/', function (req, res) {
res.send('Hello World');
});
app.listen(3000);
const { DatadomeHttp } = require('@datadome/module-http');
const http = require('http');
const datadomeClient = new DatadomeHttp('Some Key');
const server = http.createServer(async (req, res) => {
const { result, error, enrichedHeaders } = await datadomeClient.handleRequest(req, res);
if (enrichedHeaders) {
for (const [key, value] of Object.entries(enrichedHeaders)) {
console.log(`Enriched header ${key}: ${value}`);
}
}
if (result === 'ALLOW') {
console.log('Request allowed');
if (error) {
console.error(error);
}
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
} else {
console.log('Request challenged');
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Using nonce values for CSP
The HTTP Content-Security-Policy (CSP) script-src
directive specifies valid sources for scripts to be loaded on a page.
If you are using this feature, you should provide the nonce
field with a value generated by the application for each response:
const { DatadomeExpress } = require('@datadome/module-express');
const express = require('express');
const app = express();
const datadomeClient = new DatadomeExpress('Some Key');
const params = { nonce: 'your_value' };
// Usage with middleware method
app.use(datadomeClient.middleware(params));
// Usage with handleRequest method
app.use(async (req, res, next) => {
const { result, enrichedHeaders, error } = await datadomeClient.handleRequest(req, res, params);
if (result === 'ALLOW') {
console.log('Request allowed');
if (error) {
console.error(error);
}
next();
} else {
console.log('Request challenged');
}
});
app.get('/', function (req, res) {
res.send('Hello World');
});
app.listen(3000);
const { DatadomeHttp } = require('@datadome/module-http');
const http = require('http');
const datadomeClient = new DatadomeHttp('Some Key');
const server = http.createServer(async (req, res) => {
const params = { nonce: 'your_value' };
const { result, error } = await datadomeClient.handleRequest(req, res, params);
if (result === 'ALLOW') {
console.log('Request allowed');
if (error) {
console.error(error);
}
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
} else {
console.log('Request challenged');
}
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Updated 20 days ago