Mercurial > hg > nginx-site
view xml/ru/docs/njs/examples.xml @ 3014:c0a4a4a55e45
Documented Periodic Session object in njs Reference.
author | Yaroslav Zhuravlev <yar@nginx.com> |
---|---|
date | Fri, 29 Sep 2023 20:06:59 +0100 |
parents | 24b379907b0f |
children | 9eadb98ec770 |
line wrap: on
line source
<?xml version="1.0"?> <!-- Copyright (C) Nginx, Inc. --> <!DOCTYPE article SYSTEM "../../../../dtd/article.dtd"> <article name="Примеры использования" link="/ru/docs/njs/examples.html" lang="ru" rev="21"> <section id="summary"> <para> Примеры работают начиная с версии <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-авторизация"> <section id="jwt" name="Создание 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="Создание secure_link хэша"> <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="Получение произвольного поля JWT как значение переменной nginx"> <para> В данном примере из JWT payload извлекается поле <literal>sub</literal>. JWT-токен извлекается из заголовка <header>Authorization</header>. </para> <para> <path>nginx.conf</path>: <example> js_import http.js; js_set $jwt_payload_sub http.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; // в случае, если токен передаётся как аргумент "myjwt" // return jwt(r.args.myjwt).payload.sub; } export default {jwt_payload_sub}; </example> </para> </section> </section> <section id="http_proxying" name="HTTP-проксирование"> <section id="subrequest" name="Доступ к API из подзапроса"> <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> async function set_keyval(r) { let res = await r.subrequest('/api/7/http/keyvals/foo', { method: 'POST', body: JSON.stringify({ foo: 789, bar: "ss dd 00" })}); if (res.status >= 300) { r.return(res.status, res.responseBody); return; } r.return(200); } async function version(r) { let res = await r.subrequest('/api/7/nginx', { method: 'GET' }); 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> <note> Директивы <link doc="../http/ngx_http_keyval_module.xml" id="keyval"/>, <link doc="../http/ngx_http_keyval_module.xml" id="keyval_zone"/> и <link doc="../http/ngx_http_api_module.xml" id="api"/> доступны как часть <commercial_version>коммерческой подписки</commercial_version>. </note> </para> </section> <section id="fast_response" name="Возвращение самого быстрого ответа от прокси"> <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="Построение цепочки подзапросов"> <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> async function content(r) { try { let reply = await r.subrequest('/auth'); let response = JSON.parse(reply.responseBody); let token = response['token']; if (!token) { throw new Error("token is not available"); } let backend_reply = await r.subrequest('/backend', `token=${token}`); r.return(backend_reply.status, backend_reply.responseBody); } catch (e) { r.error(e); r.return(500); } } export default {content}; </example> </para> </section> </section> <section id="misc" name="Разное"> <section id="redirect" name="Внутренняя переадресация"> <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="Запись в лог количества запросов от клиента"> <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> Директивы <link doc="../http/ngx_http_keyval_module.xml" id="keyval"/> и <link doc="../http/ngx_http_keyval_module.xml" id="keyval_zone"/> доступны как часть <commercial_version>коммерческой подписки</commercial_version>. </note> </para> </section> </section> </article>