Mercurial > hg > nginx-site
view xml/en/docs/njs/examples.xml @ 2741:4fb1aaad4182
njs-0.6.0.
author | Yaroslav Zhuravlev <yar@nginx.com> |
---|---|
date | Wed, 16 Jun 2021 13:50:54 +0100 |
parents | 4849fa0fd4b4 |
children | 9cafae0b7ef3 |
line wrap: on
line source
<?xml version="1.0"?> <!-- Copyright (C) Nginx, Inc. --> <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> <article name="Examples" link="/en/docs/njs/examples.html" lang="en" rev="18"> <section id="summary"> <para> The examples work since <link doc="../njs/changes.xml" id="njs0.4.0">0.4.0</link>. </para> </section> <section id="helloword" name="Hello World"> <para> <path>nginx.conf</path>: <example> events {} http { js_import http.js; server { listen 8000; location / { js_content http.hello; } } } </example> </para> <para> <literal>http.js</literal>: <example> function hello(r) { r.return(200, "Hello world!"); } export default {hello}; </example> </para> </section> <section id="http_auth" name="HTTP Аuthorization"> <section id="jwt" name="Creating HS JWT"> <para> <path>nginx.conf</path>: <example> js_import http.js; js_set $jwt http.jwt; </example> </para> <para> <path>http.js</path>: <example> 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}; </example> </para> </section> <section id="secure_link" name="Creating secure_link Hash"> <para> <path>nginx.conf</path>: <example> 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 /; } </example> </para> <para> <path>http.js</path>: <example> function create_secure_link(r) { return require('crypto').createHash('md5') .update(r.uri).update(" mykey") .digest('base64url'); } export default {create_secure_link}; </example> </para> </section> <section id="jwt_field" name="Getting Arbitrary Field from JWT as nginx Variable"> <para> <path>nginx.conf</path>: <example> js_import http.js; js_set $jwt_payload_sub main.jwt_payload_sub; server { ... location /jwt { return 200 $jwt_payload_sub; } } </example> </para> <para> <path>http.js</path>: <example> 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} </example> </para> </section> </section> <section id="http_proxying" name="HTTP Proxying"> <section id="subrequest" name="Accessing API from a Subrequest"> <para> <path>nginx.conf</path>: <example> 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; } </example> </para> <para> <path>http.js</path>: <example> 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}; </example> </para> </section> <section id="fast_response" name="Returning Fastest Response from Proxy"> <para> <path>nginx.conf</path>: <example> js_import http.js; location /start { js_content http.content; } location /foo { proxy_pass http://backend1; } location /bar { proxy_pass http://backend2; } </example> </para> <para> <path>http.js</path>: <example> 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}; </example> </para> </section> <section id="subrequests_chaining" name="Subrequests Chaining"> <para> <path>nginx.conf</path>: <example> js_import http.js; location /start { js_content http.content; } location /auth { proxy_pass http://auth_backend; } location /backend { proxy_pass http://backend; } </example> </para> <para> <path>http.js</path>: <example> 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}; </example> </para> </section> </section> <section id="misc" name="Miscellaneous"> <section id="redirect" name="Internal Redirect"> <para> <path>nginx.conf</path>: <example> js_import http.js; location /redirect { js_content http.redirect; } location @named { return 200 named; } </example> </para> <para> <path>http.js</path>: <example> function redirect(r) { r.internalRedirect('@named'); } export default {redirect}; </example> </para> </section> <section id="requests" name="Logging the Number of Requests Per Client"> <para> <path>nginx.conf</path>: <example> 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; } } </example> </para> <para> <path>http.js</path>: <example> 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}; </example> <note> The <link doc="../http/ngx_http_keyval_module.xml" id="keyval"/> and <link doc="../http/ngx_http_keyval_module.xml" id="keyval_zone"/> directives are available as part of our <commercial_version>commercial subscription</commercial_version>. </note> </para> </section> </section> </article>