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.
Compatibility
- Node.js >= 18.x
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 |
---|---|---|
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)$ |
endpointHost | Host of the Protection API. | 'api.datadome.co' |
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 about 1 month ago