Examples
- Hello World
- HTTP Аuthorization
- Creating HS JWT
- Creating secure_link Hash
- Getting Arbitrary Field from JWT as nginx Variable
- HTTP Proxying
- Accessing API from a Subrequest
- Returning Fastest Response from Proxy
- Subrequests Chaining
- Miscellaneous
- Internal Redirect
- Logging the Number of Requests Per Client
The examples work since 0.4.0.
Hello World
nginx.conf
:
events {} http { js_import http.js; server { listen 8000; location / { js_content http.hello; } } }
http.js
:
function hello(r) { r.return(200, "Hello world!"); } export default {hello};
HTTP Аuthorization
Creating HS JWT
nginx.conf
:
js_import http.js; js_set $jwt http.jwt;
http.js
:
function generate_hs256_jwt(claims, key, valid) { var header = { typ: "JWT", alg: "HS256" }; var claims = Object.assign(claims, {exp: Math.floor(Date.now()/1000) + valid}); var s = [header, claims].map(JSON.stringify) .map(v=>v.toString('base64url')) .join('.'); var h = require('crypto').createHmac('sha256', key); return s + '.' + h.update(s).digest('base64url'); } function jwt(r) { var claims = { iss: "nginx", sub: "alice", foo: 123, bar: "qq", zyx: false }; return generate_hs256_jwt(claims, 'foo', 600); } export default {jwt};
Creating secure_link Hash
nginx.conf
:
js_import http.js; js_set $new_foo http.create_secure_link; ... location / { secure_link $cookie_foo; secure_link_md5 "$uri mykey"; ... } location @login { add_header Set-Cookie "foo=$new_foo; Max-Age=60"; return 302 /; }
http.js
:
function create_secure_link(r) { return require('crypto').createHash('md5') .update(r.uri).update(" mykey") .digest('base64url'); } export default {create_secure_link};
Getting Arbitrary Field from JWT as nginx Variable
nginx.conf
:
js_import http.js; js_set $jwt_payload_sub main.jwt_payload_sub; server { ... location /jwt { return 200 $jwt_payload_sub; } }
http.js
:
function jwt(data) { var parts = data.split('.').slice(0,2) .map(v=>Buffer.from(v, 'base64url').toString()) .map(JSON.parse); return { headers:parts[0], payload: parts[1] }; } function jwt_payload_sub(r) { return jwt(r.headersIn.Authorization.slice(7)).payload.sub; } export default {jwt_payload_sub}
HTTP Proxying
Accessing API from a Subrequest
nginx.conf
:
js_import http.js; keyval_zone zone=foo:10m; ... location /keyval { js_content http.set_keyval; } location /version { js_content http.version; } location /api { api write=on; }
http.js
:
function set_keyval(r) { r.subrequest('/api/5/http/keyvals/foo', { method: 'POST', body: JSON.stringify({ foo: 789, bar: "ss dd 00" })}, function(res) { if (res.status >= 300) { r.return(res.status, res.responseBody); return; } r.return(500); }); } function version(r) { r.subrequest('/api/5/nginx', { method: 'GET' }, function(res) { if (res.status != 200) { r.return(res.status); return; } var json = JSON.parse(res.responseBody); r.return(200, json.version); }); } export default {set_keyval, version};
Returning Fastest Response from Proxy
nginx.conf
:
js_import http.js; location /start { js_content http.content; } location /foo { proxy_pass http://backend1; } location /bar { proxy_pass http://backend2; }
http.js
:
function content(r) { var n = 0; function done(res) { if (n++ == 0) { r.return(res.status, res.responseBody); } } r.subrequest('/foo', r.variables.args, done); r.subrequest('/bar', r.variables.args, done); } export default {content};
Subrequests Chaining
nginx.conf
:
js_import http.js; location /start { js_content http.content; } location /auth { proxy_pass http://auth_backend; } location /backend { proxy_pass http://backend; }
http.js
:
function content(r) { r.subrequest('/auth') .then(reply => JSON.parse(reply.responseBody)) .then(response => { if (!response['token']) { throw new Error("token is not available"); } return reply['token']; }) .then(token => { r.subrequest('/backend', `token=${token}`) .then(reply => r.return(reply.status, reply.responseBody)); }) .catch(_ => r.return(500)); } export default {content};
Miscellaneous
Internal Redirect
nginx.conf
:
js_import http.js; location /redirect { js_content http.redirect; } location @named { return 200 named; }
http.js
:
function redirect(r) { r.internalRedirect('@named'); } export default {redirect};
Logging the Number of Requests Per Client
nginx.conf
:
js_import http.js; js_set $num_requests http.num_requests; keyval_zone zone=foo:10m; keyval $remote_addr $foo zone=foo; log_format bar '$remote_addr [$time_local] $num_requests'; access_log logs/access.log bar; server { listen 8000; location / { root html; } }
http.js
:
function num_requests(r) { var n = r.variables.foo; n = n ? Number(n) + 1 : 1; r.variables.foo = n; return n; } export default {num_requests};
The keyval and keyval_zone directives are available as part of our commercial subscription.
© 2002-2021 Igor Sysoev
© 2011-2021 Nginx, Inc.
Licensed under the BSD License.
https://nginx.org/en/docs/njs/examples.html