<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Ruby China 社区 Nginx 节点</title>
    <link>https://ruby-china.org/</link>
    <description>Ruby China 社区 Nginx 节点最新发帖。</description>
    <item>
      <title>把自己过去用的很不错的 WAF 开源了</title>
      <description>&lt;h2 id="github:"&gt;github:&lt;/h2&gt;
&lt;p&gt;地址：
WAF: &lt;a href="https://github.com/sg552/banana-waf" rel="nofollow" target="_blank"&gt;https://github.com/sg552/banana-waf&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;后台：&lt;a href="https://github.com/sg552/banana-waf-admin" rel="nofollow" target="_blank"&gt;https://github.com/sg552/banana-waf-admin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BananaWaf 是个超级简单但是实用的防火墙。与 Openresty + Nginx 集成，可以轻松防御绝大部分的恶意请求。包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQLI&lt;/li&gt;
&lt;li&gt;XSS&lt;/li&gt;
&lt;li&gt;恶意后缀扫描&lt;/li&gt;
&lt;li&gt;恶意 POC、参数&lt;/li&gt;
&lt;li&gt;指定某个 URL 的访问频率&lt;/li&gt;
&lt;li&gt;防止客户端使用 F12&lt;/li&gt;
&lt;li&gt;返回迷惑性的 response, 可以定制 (例如 java 项目返回 php 报错页面)&lt;/li&gt;
&lt;li&gt;还具备一个管理后台，可以设置对应 URL 的访问频率（另外是个项目，等会儿更新）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;优点：&lt;/p&gt;

&lt;p&gt;超级快速集成
    访问速度在很弱的开发服务器达到 9000 每秒，还没有进一步测试生产环境。（欢迎 PR）
    具备优秀的管理后台，可以查看防御情况（对手 IP，工具手段，参数）&lt;/p&gt;</description>
      <author>sg552sg552</author>
      <pubDate>Tue, 26 Oct 2021 11:34:58 +0800</pubDate>
      <link>https://ruby-china.org/topics/41801</link>
      <guid>https://ruby-china.org/topics/41801</guid>
    </item>
    <item>
      <title>飞书 + Lua 实现企业级组织架构登录认证</title>
      <description>&lt;p&gt;&lt;img src="https://pic3.zhimg.com/v2-6f1ed5de3e7587b848024b63c40e2ba5_r.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;飞书是字节跳动旗下一款企业级协同办公软件，本文将介绍如何基于飞书开放平台的身份验证能力，使用 Lua 实现企业级组织架构的登录认证网关。&lt;/p&gt;
&lt;h2 id="登录流程"&gt;登录流程&lt;/h2&gt;
&lt;p&gt;让我们首先看一下飞书第三方网站免登的整体流程：&lt;/p&gt;

&lt;p&gt;第一步：网页后端发现用户未登录，请求身份验证；
第二步：用户登录后，开放平台生成登录预授权码，302 跳转至重定向地址；
第三步：网页后端调用获取登录用户身份校验登录预授权码合法性，获取到用户身份；
第四步：如需其他用户信息，网页后端可调用获取用户信息（身份验证）。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://sf3-cn.feishucdn.com/obj/website-img/faf8b877126e0a5bc7e76f7bc955c352_CCgGABCJpR.png" title="" alt="浏览器内网页登录"&gt;&lt;/p&gt;
&lt;h2 id="Lua 实现"&gt;Lua 实现&lt;/h2&gt;&lt;h3 id="飞书接口部分实现"&gt;飞书接口部分实现&lt;/h3&gt;&lt;h4 id="获取应用的 access_token"&gt;获取应用的 access_token&lt;/h4&gt;&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;get_app_access_token&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;app_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;app_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;app_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;app_secret&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"tenant_access_token"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="通过回调 code 获取登录用户信息"&gt;通过回调 code 获取登录用户信息&lt;/h4&gt;&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;get_login_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;app_access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;get_app_access_token&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;app_access_token&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"get app_access_token failed: "&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://open.feishu.cn/open-apis/authen/v1/access_token"&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Authorization&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Bearer "&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;app_access_token&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;grant_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"authorization_code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http_post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="获取用户详细信息"&gt;获取用户详细信息&lt;/h4&gt;
&lt;p&gt;获取登录用户信息时无法获取到用户的部门信息，故这里需要使用登录用户信息中的 &lt;code&gt;open_id&lt;/code&gt; 获取用户的详细信息，同时 &lt;code&gt;user_access_token&lt;/code&gt; 也是来自于获取到的登录用户信息。&lt;/p&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;open_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://open.feishu.cn/open-apis/contact/v3/users/"&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;open_id&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Authorization&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Bearer "&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;user_access_token&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;http_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="登录信息"&gt;登录信息&lt;/h3&gt;&lt;h4 id="JWT 登录凭证"&gt;JWT 登录凭证&lt;/h4&gt;
&lt;p&gt;我们使用 JWT 作为登录凭证，同时用于保存用户的 &lt;code&gt;open_id&lt;/code&gt; 和 &lt;code&gt;department_ids&lt;/code&gt;。&lt;/p&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- 生成 token&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sign_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;open_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"open_id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;open_id&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;open_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"invalid open_id"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;department_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"department_ids"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;department_ids&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;department_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="s2"&gt;"table"&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"invalid department_ids"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jwt_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;typ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;alg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt_header_alg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;exp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jwt_expire&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;open_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;department_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;department_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;-- 验证与解析 token&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;verify_token&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cookie_feishu_auth_token&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"token not found"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jwt_secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jwt_obj: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"valid"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"department_ids"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"open_id"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"invalid token: "&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"invalid token: "&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="使用 Cookie 存储登录凭证"&gt;使用 Cookie 存储登录凭证&lt;/h4&gt;&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Set-Cookie"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cookie_key&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="s2"&gt;"="&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="组织架构白名单"&gt;组织架构白名单&lt;/h3&gt;
&lt;p&gt;我们在用户登录时获取用户的部门信息，或者在用户后续访问应用时解析登录凭证中的部门信息，根据设置的部门白名单，判断用户是否拥有访问应用的权限。&lt;/p&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- 部门白名单配置&lt;/span&gt;
&lt;span class="n"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department_whitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;check_user_access&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department_whitelist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="s2"&gt;"table"&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"department_whitelist is not a table"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department_whitelist&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;department_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"department_ids"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;department_ids&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;department_ids&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;department_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="s2"&gt;"table"&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="n"&gt;department_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;department_ids&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="n"&gt;department_ids&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;has_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department_whitelist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;department_ids&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="更多网关配置"&gt;更多网关配置&lt;/h3&gt;
&lt;p&gt;同时支持 IP 黑名单和路由白名单配置。&lt;/p&gt;
&lt;pre class="highlight lua"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- IP 黑名单配置&lt;/span&gt;
&lt;span class="n"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ip_blacklist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="c1"&gt;-- 路由白名单配置&lt;/span&gt;
&lt;span class="n"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uri_whitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;_M&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;request_uri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;
    &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"request uri: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;has_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uri_whitelist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"uri in whitelist: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_uri&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;request_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote_addr&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;has_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ip_blacklist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"forbided ip: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request_ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_FORBIDDEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request_uri&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logout_uri&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kd"&gt;local&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;verify_token&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;check_user_access&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"user access not permitted"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;clear_token&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sso&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ngx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ERR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"verify token failed: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request_uri&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;callback_uri&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sso&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;sso_callback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="使用"&gt;使用&lt;/h2&gt;
&lt;p&gt;本文就不赘述 OpenResty 的安装了，可以参考我的另一篇文章&lt;a href="https://k8scat.com/posts/linux/install-openresty-on-ubuntu-from-source-code/" rel="nofollow" target="_blank" title=""&gt;《在 Ubuntu 上使用源码安装 OpenResty》&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id="下载"&gt;下载&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to
git clone git@github.com:ledgetech/lua-resty-http.git
git clone git@github.com:SkyLothar/lua-resty-jwt.git
git clone git@github.com:k8scat/lua-resty-feishu-auth.git
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="配置"&gt;配置&lt;/h3&gt;&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;lua_package_path&lt;/span&gt; &lt;span class="s2"&gt;"/path/to/lua-resty-feishu-auth/lib/?.lua;/path/to/lua-resty-jwt/lib/?.lua;/path/to/lua-resty-http/lib/?.lua;/path/to/lua-resty-redis/lib/?.lua;/path/to/lua-resty-redis-lock/lib/?.lua;;"&lt;/span&gt;;

&lt;span class="n"&gt;server&lt;/span&gt; {
    &lt;span class="n"&gt;access_by_lua_block&lt;/span&gt; {
        &lt;span class="n"&gt;local&lt;/span&gt; &lt;span class="n"&gt;feishu_auth&lt;/span&gt; = &lt;span class="n"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"resty.feishu_auth"&lt;/span&gt;
        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;app_id&lt;/span&gt; = &lt;span class="s2"&gt;""&lt;/span&gt;
        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;app_secret&lt;/span&gt; = &lt;span class="s2"&gt;""&lt;/span&gt;
        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;callback_uri&lt;/span&gt; = &lt;span class="s2"&gt;"/feishu_auth_callback"&lt;/span&gt;
        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;logout_uri&lt;/span&gt; = &lt;span class="s2"&gt;"/feishu_auth_logout"&lt;/span&gt;
        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;app_domain&lt;/span&gt; = &lt;span class="s2"&gt;"feishu-auth.example.com"&lt;/span&gt;

        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;jwt_secret&lt;/span&gt; = &lt;span class="s2"&gt;"thisisjwtsecret"&lt;/span&gt;

        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;ip_blacklist&lt;/span&gt; = {&lt;span class="s2"&gt;"47.1.2.3"&lt;/span&gt;}
        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;uri_whitelist&lt;/span&gt; = {&lt;span class="s2"&gt;"/"&lt;/span&gt;}
        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;.&lt;span class="n"&gt;department_whitelist&lt;/span&gt; = {&lt;span class="s2"&gt;"0"&lt;/span&gt;}

        &lt;span class="n"&gt;feishu_auth&lt;/span&gt;:&lt;span class="n"&gt;auth&lt;/span&gt;()
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="配置说明"&gt;配置说明&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app_id&lt;/code&gt; 用于设置飞书企业自建应用的 &lt;code&gt;App ID&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app_secret&lt;/code&gt; 用于设置飞书企业自建应用的 &lt;code&gt;App Secret&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;callback_uri&lt;/code&gt; 用于设置飞书网页登录后的回调地址（需在飞书企业自建应用的安全设置中设置重定向 URL）&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;logout_uri&lt;/code&gt; 用于设置登出地址&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app_domain&lt;/code&gt; 用于设置访问域名（需和业务服务的访问域名一致）&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;jwt_secret&lt;/code&gt; 用于设置 JWT secret&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ip_blacklist&lt;/code&gt; 用于设置 IP 黑名单&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;uri_whitelist&lt;/code&gt; 用于设置地址白名单，例如首页不需要登录认证&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;department_whitelist&lt;/code&gt; 用于设置部门白名单（字符串）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="应用权限说明"&gt;应用权限说明&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;获取部门基础信息&lt;/li&gt;
&lt;li&gt;获取部门组织架构信息&lt;/li&gt;
&lt;li&gt;以应用身份读取通讯录&lt;/li&gt;
&lt;li&gt;获取用户组织架构信息&lt;/li&gt;
&lt;li&gt;获取用户基本信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="开源"&gt;开源&lt;/h2&gt;
&lt;p&gt;本项目已完成且已在 GitHub 上开源：&lt;a href="https://github.com/k8scat/lua-resty-feishu-auth" rel="nofollow" target="_blank" title=""&gt;k8scat/lua-resty-feishu-auth&lt;/a&gt;，希望大家可以动动手指点个 Star，表示对本项目的肯定与支持！&lt;/p&gt;</description>
      <author>k8scat</author>
      <pubDate>Fri, 03 Sep 2021 23:51:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/41653</link>
      <guid>https://ruby-china.org/topics/41653</guid>
    </item>
    <item>
      <title>【分享】Inside NGINX: How We Designed for Performance &amp; Scale</title>
      <description>&lt;p&gt;&lt;a href="https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/" rel="nofollow" target="_blank"&gt;https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/&lt;/a&gt;&lt;/p&gt;</description>
      <author>yfractal</author>
      <pubDate>Thu, 26 Mar 2020 09:54:21 +0800</pubDate>
      <link>https://ruby-china.org/topics/39669</link>
      <guid>https://ruby-china.org/topics/39669</guid>
    </item>
    <item>
      <title>Rails 项目部署腾讯 Ubuntu 16.04,部署报错 We're sorry, but something went wrong.</title>
      <description>&lt;p&gt;我在终端跑 cap production deploy 没有报错而是直接退出&lt;img src="https://l.ruby-china.com/photo/2020/d57dae03-b8c6-4cf0-abcf-d7afcd11e809.png!large" title="" alt=""&gt;
然后我在浏览器输入我的服务器 ip
&lt;img src="https://l.ruby-china.com/photo/2020/4447f421-bc78-4fad-871b-cb0906a6cf0d.png!large" title="" alt=""&gt;
这个是我的 log 文件
&lt;img src="https://l.ruby-china.com/photo/2020/aac3e825-dc84-448e-9b01-00f4fe80966d.png!large" title="" alt=""&gt;
我是跟着这个文档操作的 &lt;a href="https://gorails.com/deploy/ubuntu/16.04" rel="nofollow" target="_blank"&gt;https://gorails.com/deploy/ubuntu/16.04&lt;/a&gt;
我是一个小白之前几次部署也遇到这种情况一直没有解决，求各位老师指点。谢谢。&lt;/p&gt;</description>
      <author>korey</author>
      <pubDate>Fri, 06 Mar 2020 12:15:57 +0800</pubDate>
      <link>https://ruby-china.org/topics/39567</link>
      <guid>https://ruby-china.org/topics/39567</guid>
    </item>
    <item>
      <title>PHP 7 安装日志</title>
      <description>&lt;h2 id="前奏，安装gcc 5以上，我安装了8"&gt;前奏，安装 gcc 5 以上，我安装了 8&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;请看这个链接 &lt;a href="https://www.cnblogs.com/ToBeExpert/p/10297697.html" rel="nofollow" target="_blank"&gt;https://www.cnblogs.com/ToBeExpert/p/10297697.html&lt;/a&gt; ，文章的最后是高潮&lt;/li&gt;
&lt;li&gt;这么说吧我编译 gcc8 用了 5-6 个小时，配置，windows2012 的 vmware，cpu2x2，显示 4，内存 2G 有需要虚拟机的可以找我要&lt;/li&gt;
&lt;li&gt;虚拟机的问题，死活连不上网，这个可能和 dhcp 有关系，桥接然后静态 ip，解决问题，这个花了一天的时间，如果要深入理解桥接和 nat，估计只有学思科或者华为认证了&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="过程连接"&gt;过程连接&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.cnblogs.com/dj0325/p/8481092.html" rel="nofollow" target="_blank" title=""&gt;scl 安装 gcc-把 4 改成 8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cnblogs.com/ToBeExpert/p/10297697.html" rel="nofollow" target="_blank" title=""&gt;CentOS 7 升级 gcc/g++ 编译器，我的是 centos6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.cnblogs.com/Jordandan/p/10402912.html" rel="nofollow" target="_blank" title=""&gt;编译 nginx 的时候报错 需要安装 PCRE&lt;/a&gt; 2019 年 11 月 28 日 09:24:16&lt;/li&gt;
&lt;li&gt;pcre 是一个正则表达式库&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cnblogs.com/selectztl/p/9473967.html" rel="nofollow" target="_blank" title=""&gt;nginx 的下载和配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.csdn.net/nouswait/article/details/83105378" rel="nofollow" target="_blank" title=""&gt;php+nginx mysql 那块没有借鉴&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cnblogs.com/chancy/p/9238149.html" rel="nofollow" target="_blank" title=""&gt;linux 安装 php7.2.7&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="补上非root php"&gt;补上非 root php&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;前奏 我把 nginx 和 php 都放在环境变量里面了，php 启动的话就是 php-fpm&lt;/li&gt;
&lt;li&gt;补能让 php 文件都用 root 权限上传吧！&lt;/li&gt;
&lt;li&gt;学习，linux 用户和组，自己创建&lt;/li&gt;
&lt;li&gt;php-fpm 的关闭，我是查找进程一个个关闭的，大概有 3-4 个进程，网上的看不懂&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="重点"&gt;重点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.cnblogs.com/lobtao/articles/9124989.html" rel="nofollow" target="_blank" title=""&gt;Nginx 访问 PHP 文件的 File not found 错误处理，两种情况&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;我花了一点时间搞定的编辑 etc/php-fpm.d/&lt;a href="http://www.conf" rel="nofollow" target="_blank" title=""&gt;www.conf&lt;/a&gt; 文件 查找 user 和 group，之前已经说过了，你懂的&lt;/li&gt;
&lt;li&gt;默认查找 php-fpm 的进程是有 nobody 的，改完了之后就是你想要的&lt;/li&gt;
&lt;li&gt;过程连接中有提到 nginx 和 php 关联 把路径改了，最后一个不要加斜杠！！！记住喽，&lt;/li&gt;
&lt;li&gt;配置更改 fastcgi_param  SCRIPT_FILENAME  /home/yournname/work/php/www$fastcgi_script_name&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="结尾，准备装禅道，不知道mysql驱动装好没有，接下来会写步骤"&gt;结尾，准备装禅道，不知道 mysql 驱动装好没有，接下来会写步骤&lt;/h2&gt;&lt;h2 id="xdebug很重要，不知道能否成功"&gt;xdebug 很重要，不知道能否成功&lt;/h2&gt;</description>
      <author>Ghaker</author>
      <pubDate>Thu, 28 Nov 2019 10:24:16 +0800</pubDate>
      <link>https://ruby-china.org/topics/39284</link>
      <guid>https://ruby-china.org/topics/39284</guid>
    </item>
    <item>
      <title>請問 nginx 中 server 帶有多個 location，那如何在瀏覽器中對 location 的緩存做標識</title>
      <description>&lt;p&gt;在配置反向代理的時候遇到了一個問題就是我在 nginx 中配置了 server 對應多個 location，每個 location 都是轉發到不同的目標網站
配置文件如下 CC:8083\CC:8080\CC:8088 這三個網站文件結構類似，但屬於不同的業務模塊，
現在有個問題就是我在同一瀏覽器中先訪問了 &lt;a href="http://AA/OA" rel="nofollow" target="_blank"&gt;http://AA/OA&lt;/a&gt; 網站是可以正常打開的，
然後我再去訪問&lt;a href="http://AA/OEDI" rel="nofollow" target="_blank"&gt;http://AA/OEDI&lt;/a&gt;時網站就異常了登錄成功無法正常跳轉，
後來發現是緩存文件的問題，清理文件緩存然後再去訪問&lt;a href="http://AA/OEDI" rel="nofollow" target="_blank"&gt;http://AA/OEDI&lt;/a&gt;是正常的。
首次訪問了 OA 時瀏覽器緩存了 OA 的文件，再次訪問 OEDI 時調用了 OA 的緩存導致了跳轉失敗，
請問這種問題有什麼好的決解方法嗎？如何給緩存做標識？&lt;/p&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;server&lt;/span&gt; {
       &lt;span class="n"&gt;listen&lt;/span&gt;       &lt;span class="m"&gt;80&lt;/span&gt;;
       &lt;span class="n"&gt;server_name&lt;/span&gt;  &lt;span class="n"&gt;AA&lt;/span&gt;;
       &lt;span class="n"&gt;fastcgi_read_timeout&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;; &lt;span class="c"&gt;#設置服務響應超時問題 如果不設置WEB表單加載時間長的話會報錯（s）
&lt;/span&gt;       &lt;span class="n"&gt;fastcgi_send_timeout&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;; &lt;span class="c"&gt;#設置服務響應超時問題 如果不設置WEB表單加載時間長的話會報錯（s）
&lt;/span&gt;       &lt;span class="n"&gt;client_max_body_size&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;; &lt;span class="c"&gt;#設置通過反向代理訪問web可上傳文件的最大值（m）
&lt;/span&gt;       &lt;span class="n"&gt;location&lt;/span&gt; /&lt;span class="n"&gt;OA&lt;/span&gt;/
       {       
           &lt;span class="n"&gt;root&lt;/span&gt;   &lt;span class="n"&gt;html&lt;/span&gt;;
               &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;CC&lt;/span&gt;:&lt;span class="m"&gt;8083&lt;/span&gt;/;
           &lt;span class="n"&gt;proxy_pass_request_headers&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;;
               &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;host&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://CC:8083"&lt;/span&gt; )
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;OA&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;        
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ($&lt;span class="n"&gt;document_uri&lt;/span&gt; ~ &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="n"&gt;AA&lt;/span&gt;/)
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;OA&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;        
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;Uri&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://CC:8083"&lt;/span&gt; )
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;OA&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;        
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;Uri&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://AA"&lt;/span&gt; )
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;OA&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;        
           }
       }
       &lt;span class="n"&gt;location&lt;/span&gt; /&lt;span class="n"&gt;OEDI&lt;/span&gt;/ 
       {
           &lt;span class="n"&gt;root&lt;/span&gt;   &lt;span class="n"&gt;html&lt;/span&gt;;
           &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;CC&lt;/span&gt;:&lt;span class="m"&gt;8088&lt;/span&gt;/;
           &lt;span class="c"&gt;#proxy_redirect http://$host/;
&lt;/span&gt;           &lt;span class="n"&gt;proxy_pass_request_headers&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;;
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;host&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://CC:8088"&lt;/span&gt; )
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;OEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ($&lt;span class="n"&gt;document_uri&lt;/span&gt; ~ &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="n"&gt;AA&lt;/span&gt;/)
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;OEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;Uri&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://CC:8088"&lt;/span&gt; )
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;OEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;Uri&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://AA"&lt;/span&gt; )
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;OEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }

       }
       &lt;span class="n"&gt;location&lt;/span&gt; / {
           &lt;span class="n"&gt;root&lt;/span&gt;   &lt;span class="n"&gt;html&lt;/span&gt;;
           &lt;span class="n"&gt;if&lt;/span&gt; ($&lt;span class="n"&gt;http_cookie&lt;/span&gt; ~* &lt;span class="s2"&gt;"SEDI"&lt;/span&gt;) {
                           &lt;span class="n"&gt;rewrite&lt;/span&gt;   ^/(.*)$  /&lt;span class="n"&gt;SEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="n"&gt;last&lt;/span&gt;;      
                       }
           &lt;span class="n"&gt;if&lt;/span&gt; ($&lt;span class="n"&gt;http_cookie&lt;/span&gt; ~* &lt;span class="s2"&gt;"OEDI"&lt;/span&gt;) {
                           &lt;span class="n"&gt;rewrite&lt;/span&gt;   ^/(.*)$  /&lt;span class="n"&gt;OEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="n"&gt;last&lt;/span&gt;;      
                       }
           &lt;span class="n"&gt;if&lt;/span&gt; ($&lt;span class="n"&gt;http_cookie&lt;/span&gt; ~* &lt;span class="s2"&gt;"OA"&lt;/span&gt;) {
                           &lt;span class="n"&gt;rewrite&lt;/span&gt;   ^/(.*)$  /&lt;span class="n"&gt;OA&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="n"&gt;last&lt;/span&gt;;        
                       }
       }
       &lt;span class="n"&gt;location&lt;/span&gt; /&lt;span class="n"&gt;SEDI&lt;/span&gt;/
       {       &lt;span class="n"&gt;root&lt;/span&gt;   &lt;span class="n"&gt;html&lt;/span&gt;;
               &lt;span class="n"&gt;proxy_pass&lt;/span&gt; &lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;CC&lt;/span&gt;:&lt;span class="m"&gt;8080&lt;/span&gt;/;
           &lt;span class="c"&gt;#proxy_redirect http://$host/;
&lt;/span&gt;           &lt;span class="n"&gt;proxy_pass_request_headers&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;;
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;host&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://CC:8080"&lt;/span&gt; )
           {
               &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;SEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;host&lt;/span&gt; ~ &lt;span class="s2"&gt;"http://http://AA"&lt;/span&gt; )
           {
               &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;SEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ($&lt;span class="n"&gt;document_uri&lt;/span&gt; ~ &lt;span class="n"&gt;http&lt;/span&gt;://&lt;span class="n"&gt;AA&lt;/span&gt;/)
           {
               &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;SEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;Uri&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://CC:8088"&lt;/span&gt; )
           {
                   &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;SEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }
           &lt;span class="n"&gt;if&lt;/span&gt; ( $&lt;span class="n"&gt;Uri&lt;/span&gt; ~ &lt;span class="s2"&gt;"https://AA"&lt;/span&gt; )
           {
               &lt;span class="n"&gt;rewrite&lt;/span&gt; ^/(.*)$ /&lt;span class="n"&gt;SEDI&lt;/span&gt;/$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;;      
           }
       }
   }
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>vip5529780</author>
      <pubDate>Thu, 15 Aug 2019 11:29:56 +0800</pubDate>
      <link>https://ruby-china.org/topics/38945</link>
      <guid>https://ruby-china.org/topics/38945</guid>
    </item>
    <item>
      <title>Nginx 进程和信号</title>
      <description>&lt;h2 id="Nginx 进程和信号"&gt;Nginx 进程和信号&lt;/h2&gt;&lt;h2 id="进程结构"&gt;进程结构&lt;/h2&gt;
&lt;p&gt;一般来说 Nginx 有一个父进程 Master，和一个或多个子进程。&lt;/p&gt;

&lt;p&gt;子进程分两类，一种是 Worker 进程，另一种是 Cache 相关的进程。&lt;/p&gt;

&lt;p&gt;Cache 在多个 Worker 间共享使用。同时被进程 Cache manager 和 Cache loader 使用。Cache loader 做缓存的载入，Cache manager 做缓存的管理。这些进程间的通讯都是使用共享内存来解决的。&lt;/p&gt;

&lt;p&gt;为什么不用多线程？因为线程之间是共享地址空间的，当某一个第三方模块引发了地址空间的段错误时，地址越界出现时，会导致整个进程挂掉。&lt;/p&gt;

&lt;p&gt;Nginx 希望每个 Worker 进程从头到尾占有一个 CPU，所以往往不止要把 Worker 进程的数量配置与服务器的 CPU 核数一致以外，还需要把每一个 Worker 进程与某一个 CPU 核绑定在一起。这样可以更好的使用每个 CPU 核上面的 CPU 缓存，提高缓存的命中率。&lt;/p&gt;

&lt;p&gt;不仅仅是缓存的原因，一个进程从头到尾占有一个 CPU，减少 CPU 上下文切换的次数和耗时，让 CPU 更多的时间用在运行进程上。&lt;/p&gt;
&lt;h3 id="Master 进程"&gt;Master 进程&lt;/h3&gt;
&lt;p&gt;监控 Worker 进程，接受信号&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CHLD，子进程终止的时候会向父进程发送 CHLD。Master 进程通过这个信号维持 Worker 进程的数量。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;管理 Worker 进程，发送信号&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TERM/INT，立刻停止进程。&lt;/li&gt;
&lt;li&gt;QUIT，优雅的退出，等请求处理完才退出，用户无感知。&lt;/li&gt;
&lt;li&gt;HUP，重载配置文件。&lt;/li&gt;
&lt;li&gt;USR1，重新打开日志文件，做日志文件的切割。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;下面 2 个信号，Nginx 命令行中没有对应的操作，只能通过 kill 直接向 Master 进程发送&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;USR2，热升级第一阶段，启动新进程。旧的 Nginx 主进程 Master 将会把自己的进程文件改名为 .oldbin，然后执行新版 Nginx。此时新旧 Nginx 会同时运行，共同处理请求。&lt;/li&gt;
&lt;li&gt;WINCH，热升级第二阶段，停止老进程。逐步停止旧版 Nginx 的 Worker 进程就都会随着任务执行完毕而退出，新版的 Nginx 的 Worker 进程会逐渐取代旧版 Worker 进程。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="Worker 进程"&gt;Worker 进程&lt;/h3&gt;
&lt;p&gt;和上面对应，接受信号&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TERM/INT&lt;/li&gt;
&lt;li&gt;QUIT&lt;/li&gt;
&lt;li&gt;USR1&lt;/li&gt;
&lt;li&gt;WINCH&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="Nginx 命令行"&gt;Nginx 命令行&lt;/h3&gt;
&lt;p&gt;启动 Nginx 以后，Nginx 会把 Master 进程的 pid 记录到一个文件中，一般是 Nginx 安装目录下 logs/nginx.pid。&lt;/p&gt;

&lt;p&gt;我们平时使用的命令行其实就是对这个 pid 发送对应的信号。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reload: HUP&lt;/li&gt;
&lt;li&gt;reopen: USR1&lt;/li&gt;
&lt;li&gt;stop: TERM&lt;/li&gt;
&lt;li&gt;quit: QUIT&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="reload 流程"&gt;reload 流程&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;向 Master 进程发送 HUP 信号（reload 命令）&lt;/li&gt;
&lt;li&gt;Master 进程校验配置语法是否正确&lt;/li&gt;
&lt;li&gt;Master 进程更新监听端口（比如新配置增加了监听 443 端口）&lt;/li&gt;
&lt;li&gt;Master 进程用新配置启动新的 Worker 子进程&lt;/li&gt;
&lt;li&gt;Master 进程向老 Worker 子进程发送 QUIT 信号&lt;/li&gt;
&lt;li&gt;老 Worker 子进程关闭监听句柄，处理完当前连接后结束进程&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;在 1.11.11 的版本中，增加了 worker_shutdown_timeout 参数来设置优雅退出 Worker 进程的超时时间。&lt;/p&gt;
&lt;h3 id="热升级流程"&gt;热升级流程&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;将旧 Nginx 文件换成新 Nginx 文件（注意备份）&lt;/li&gt;
&lt;li&gt;向 Master 进程发送 USR2 信号&lt;/li&gt;
&lt;li&gt;Master 进程修改 pid 文件名，加后缀 .oldbin&lt;/li&gt;
&lt;li&gt;Master 进程用新 Nginx 文件启动新 Master 进程&lt;/li&gt;
&lt;li&gt;向老 Master 进程发送 WINCH 信号，老 Master 进程会优雅关闭老 Worker 进程&lt;/li&gt;
&lt;li&gt;此时老 Master 进程依然存活，如果出现问题需要回滚。向老 Master 进程发送 HUP，然后向新 Master 发送 QUIT 即可。（注意恢复备份文件）&lt;/li&gt;
&lt;li&gt;正常升级后，通过 kill -QUIT 信号关闭老 Master 进程&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;新老 Master 进程，同时存在，那么是怎么同时监听端口的？&lt;/p&gt;

&lt;p&gt;新老 Master 进程是父子进程，所以可以同时监听。&lt;/p&gt;
&lt;h3 id="优雅关闭 Worker 进程"&gt;优雅关闭 Worker 进程&lt;/h3&gt;
&lt;p&gt;优雅关闭是指 HTTP 请求，如果代理的是 WebSocket、TCP、UDP，这时候 Nginx 是无法进行优雅关闭的。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;设置定时器（这个功能默认不开启，配置文件有设置 worker_shutdown_timeout 才会生效）&lt;/li&gt;
&lt;li&gt;关闭监听句柄&lt;/li&gt;
&lt;li&gt;关闭空闲连接&lt;/li&gt;
&lt;li&gt;在循环中等待全部连接关闭（如果设置了 worker_shutdown_timeout，超时后会强制关闭全部连接）&lt;/li&gt;
&lt;li&gt;退出进程&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;更多信息可以参考官方文档 &lt;a href="https://www.nginx.com/resources/wiki/start/topics/tutorials/commandline/" rel="nofollow" target="_blank" title=""&gt;Starting, Stopping, and Restarting NGINX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;原文转自博客 &lt;a href="https://www.tuliang.org/nginx-jin-cheng-he-xin-hao/" rel="nofollow" target="_blank" title=""&gt;Nginx 进程和信号&lt;/a&gt;&lt;/p&gt;</description>
      <author>tuliang</author>
      <pubDate>Sun, 02 Dec 2018 10:49:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/37845</link>
      <guid>https://ruby-china.org/topics/37845</guid>
    </item>
    <item>
      <title>负载均衡的两台服务器里的项目，如何实现 public 下的资源共享</title>
      <description>&lt;p&gt;访问 A 服务器的一张图片，404 之后再去 B 尝试一下，这种方案是否可行&lt;/p&gt;</description>
      <author>ad583255925</author>
      <pubDate>Tue, 28 Aug 2018 17:49:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/37399</link>
      <guid>https://ruby-china.org/topics/37399</guid>
    </item>
    <item>
      <title>有没有办法在 Nginx 记录给用户发送的页面内容</title>
      <description>&lt;p&gt;因为使用 nginx 反向代理，页面被插入了跳转代码，跳转到一个广告链接。不确定是服务器出的问题还是代理服务器出的问题。想在代理服务器的 nginx 上做个日志记录，记录每次请求发送给用户的 html 页面的内容，有没有从 nginx 入手的办法？&lt;/p&gt;</description>
      <author>gaicitadie</author>
      <pubDate>Fri, 13 Jul 2018 17:33:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/37152</link>
      <guid>https://ruby-china.org/topics/37152</guid>
    </item>
    <item>
      <title>网站反映慢,经常出现卡死</title>
      <description>&lt;p&gt;我的服务器同时部署啦 homeland 和 redmine,redmine 访问无压力，很快，但是 homenald 就经常卡死，配置 ubuntu16.04, 4 核 8gb，使用的是 nginx+passenger, 不要问我为什么用论坛做文章，我也很无奈。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3541 4919/T7 age/Cor/CoreMain.cpp:616 &lt;span class="o"&gt;]&lt;/span&gt;: Signal received. Gracefully shutting down... &lt;span class="o"&gt;(&lt;/span&gt;send signal 2 more &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt; to force shutdown&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3543 4919/T1 age/Cor/CoreMain.cpp:1161 &lt;span class="o"&gt;]&lt;/span&gt;: Received &lt;span class="nb"&gt;command &lt;/span&gt;to shutdown gracefully. Waiting &lt;span class="k"&gt;until &lt;/span&gt;all clients have disconnected...
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3543 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 20897, application /jxredmine &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3573 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 5310, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3617 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 32529, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3645 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 32553, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3695 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 32725, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3695 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 421, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3773 4919/T7 Ser/Server.h:903 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ServerThr.1] Freed 0 spare client objects
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3773 4919/T7 Ser/Server.h:559 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ServerThr.1] Shutdown finished
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3774 4919/Tf Ser/Server.h:903 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ApiServer] Freed 0 spare client objects
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.3774 4919/Tf Ser/Server.h:559 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ApiServer] Shutdown finished
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.4396 4919/Td Ser/Server.h:903 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ServerThr.4] Freed 0 spare client objects
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.4396 4919/Td Ser/Server.h:559 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ServerThr.4] Shutdown finished
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.5251 4919/T9 Ser/Server.h:903 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ServerThr.2] Freed 0 spare client objects
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.5252 4919/T9 Ser/Server.h:559 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ServerThr.2] Shutdown finished
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.5462 4919/Tb Ser/Server.h:903 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ServerThr.3] Freed 0 spare client objects
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.5462 4919/Tb Ser/Server.h:559 &lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;ServerThr.3] Shutdown finished
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.5463 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 20897, application //jxredmine &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.7471 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 5310, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.7472 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 32529, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.7472 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 32553, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.7473 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 32725, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:06.7473 4919/T1 age/Cor/CoreMain.cpp:1075 &lt;span class="o"&gt;]&lt;/span&gt;: Checking whether to disconnect long-running connections &lt;span class="k"&gt;for &lt;/span&gt;process 421, application /jxcatbbs &lt;span class="o"&gt;(&lt;/span&gt;production&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:07.1117 4919/T1 age/Cor/CoreMain.cpp:1234 &lt;span class="o"&gt;]&lt;/span&gt;: Passenger core shutdown finished
2018/05/31 10:05:07 &lt;span class="o"&gt;[&lt;/span&gt;info] 1432#1432: Using 32768KiB of shared memory &lt;span class="k"&gt;for &lt;/span&gt;nchan &lt;span class="k"&gt;in&lt;/span&gt; /etc/nginx/nginx.conf:77
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:07.4512 1438/T1 age/Wat/WatchdogMain.cpp:1258 &lt;span class="o"&gt;]&lt;/span&gt;: Starting Passenger watchdog...
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:07.4760 1441/T1 age/Cor/CoreMain.cpp:1249 &lt;span class="o"&gt;]&lt;/span&gt;: Starting Passenger core...
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:07.4762 1441/T1 age/Cor/CoreMain.cpp:252 &lt;span class="o"&gt;]&lt;/span&gt;: Passenger core running &lt;span class="k"&gt;in &lt;/span&gt;multi-application mode.
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:07.4897 1441/T1 age/Cor/CoreMain.cpp:984 &lt;span class="o"&gt;]&lt;/span&gt;: Passenger core online, PID 1441
App 1467 stdout:
&lt;span class="o"&gt;[&lt;/span&gt; N 2018-05-31 10:05:12.2656 1441/T5 age/Cor/SecurityUpdateChecker.h:517 &lt;span class="o"&gt;]&lt;/span&gt;: Security update check: no update found &lt;span class="o"&gt;(&lt;/span&gt;next check &lt;span class="k"&gt;in &lt;/span&gt;24 hours&lt;span class="o"&gt;)&lt;/span&gt;
App 1577 stdout:
App 1594 stdout:
App 1609 stdout:
App 1624 stdout:
App 1658 stdout:

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nginx:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;listen 443&lt;span class="p"&gt;;&lt;/span&gt;
  server_name bbs.jxcat.com&lt;span class="p"&gt;;&lt;/span&gt;
  ssl on&lt;span class="p"&gt;;&lt;/span&gt;
  root xxx/public&lt;span class="p"&gt;;&lt;/span&gt;

  passenger_enabled on&lt;span class="p"&gt;;&lt;/span&gt;

  rails_env production&lt;span class="p"&gt;;&lt;/span&gt;

  index index.html index.htm&lt;span class="p"&gt;;&lt;/span&gt;

  location / &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# First attempt to serve request as file, then&lt;/span&gt;
    &lt;span class="c"&gt;# as directory, then fall back to displaying a 404.&lt;/span&gt;
    root xxx/public&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c"&gt;# try_files $uri $uri/ =404;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;地址：bbs.jxcat.com&lt;/p&gt;</description>
      <author>tang05709</author>
      <pubDate>Thu, 31 May 2018 10:34:02 +0800</pubDate>
      <link>https://ruby-china.org/topics/36867</link>
      <guid>https://ruby-china.org/topics/36867</guid>
    </item>
    <item>
      <title>https 在 Nginx 中应该怎么配置默认就是使用 https 呢？</title>
      <description>&lt;p&gt;配置好 https 后，发现了两个问题：&lt;br&gt;
我们配置的域名是&lt;code&gt;www.xxx.com&lt;/code&gt;，但是发现 ruby china 是使用&lt;code&gt;xxx.com&lt;/code&gt;，不需要用到前面的&lt;code&gt;www&lt;/code&gt;，这两种方式的区别在哪里呢？哪 3 一种比较好。&lt;br&gt;
还有一个就是，现在访问，默认依然是使用 http，只有在使用 https 访问，才会用到 https，怎么在 nginx 配置，默认就是使用 https 呢？&lt;/p&gt;</description>
      <author>QueXuQ</author>
      <pubDate>Fri, 04 May 2018 10:25:25 +0800</pubDate>
      <link>https://ruby-china.org/topics/36677</link>
      <guid>https://ruby-china.org/topics/36677</guid>
    </item>
    <item>
      <title>想到一个 Nginx + Docker 进行热部署的方案，不知道是否有更优解</title>
      <description>&lt;p&gt;开两个 docker，一个是主 server，一个临时 server，都映射到同一个 rails 目录。&lt;/p&gt;

&lt;p&gt;在更新代码之前：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1、启动临时server
2、启动成功后修改nginx的配置文件，把端口转发到临时server，然后nginx -s reload，用临时server提供服务
3、更新代码
4、重启主server
5、等主server启动后，再把nginx的配置文件改回来，把端口转发改回主server，然后nginx -s reload，至此代码更新完毕。
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>gaicitadie</author>
      <pubDate>Mon, 26 Mar 2018 15:59:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/35325</link>
      <guid>https://ruby-china.org/topics/35325</guid>
    </item>
    <item>
      <title>****/projects 往后的所有路径匹配到一个静态文件应该如何写 loaction？</title>
      <description>&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/projects&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;/home/deploy/www/projects_vue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为这是一个前端写的项目，本来想着这样匹配到 index 就可以了，但是没想到如果访问&lt;code&gt;***/projects/orders&lt;/code&gt;之类的域名，就会出现 404，但是找了一下，没有发现相关的 nginx 该如何写这个 location，希望&lt;code&gt;/projects&lt;/code&gt;后面的所有域名的去到 index.html 中呢？多谢。&lt;/p&gt;

&lt;p&gt;根据楼下小伙伴的提示，把配置改成：&lt;/p&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="s"&gt;unix:///tmp/example.sock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;www.example.io&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/home/deploy/example_backend/current/public&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_redirect&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;if&lt;/span&gt; &lt;span class="s"&gt;(-f&lt;/span&gt; &lt;span class="nv"&gt;$request_filename&lt;/span&gt;&lt;span class="n"&gt;/index.html&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;rewrite&lt;/span&gt; &lt;span class="s"&gt;(.*)&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="n"&gt;/index.html&lt;/span&gt; &lt;span class="s"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;if&lt;/span&gt; &lt;span class="s"&gt;(-f&lt;/span&gt; &lt;span class="nv"&gt;$request_filename&lt;/span&gt;&lt;span class="s"&gt;.html)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;rewrite&lt;/span&gt; &lt;span class="s"&gt;(.*)&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s"&gt;.html&lt;/span&gt; &lt;span class="s"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;if&lt;/span&gt; &lt;span class="s"&gt;(!-f&lt;/span&gt; &lt;span class="nv"&gt;$request_filename&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://example&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kn"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/project&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;/home/deploy/example_frontend&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="n"&gt;/index.html?/&lt;/span&gt;&lt;span class="nv"&gt;$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可是仍然是原来的问题，不同的是&lt;code&gt;/project/xxxx&lt;/code&gt;这类域名，就跑去读取 rails 了，而不是 404 了。目前应该如何改进会更好？&lt;/p&gt;</description>
      <author>QueXuQ</author>
      <pubDate>Mon, 30 Oct 2017 21:46:47 +0800</pubDate>
      <link>https://ruby-china.org/topics/34471</link>
      <guid>https://ruby-china.org/topics/34471</guid>
    </item>
    <item>
      <title>配置了 https 后就返回 302 错误，自己捣鼓了快三天了，还不解决不了，请教一下各位。</title>
      <description>&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="c1"&gt;#server&lt;/span&gt;
&lt;span class="c1"&gt;#   {&lt;/span&gt;
&lt;span class="c1"&gt;#   listen 80;&lt;/span&gt;
&lt;span class="c1"&gt;#   server_name www.test.com test.com;&lt;/span&gt;
&lt;span class="c1"&gt;#   return 301 https://$server_name$request_uri;&lt;/span&gt;
&lt;span class="c1"&gt;#   &lt;/span&gt;
&lt;span class="c1"&gt;#}&lt;/span&gt;




&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;#   listen 80;&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;www.test.com&lt;/span&gt; &lt;span class="s"&gt;test.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.htm&lt;/span&gt; &lt;span class="s"&gt;index.php&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/home/www/test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

    &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/conf.d/cert/ssl.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/conf.d/cert/ssl.key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_session_timeout&lt;/span&gt; &lt;span class="mi"&gt;5m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_ciphers&lt;/span&gt; &lt;span class="s"&gt;ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_protocols&lt;/span&gt; &lt;span class="s"&gt;TLSv1&lt;/span&gt; &lt;span class="s"&gt;TLSv1.1&lt;/span&gt; &lt;span class="s"&gt;TLSv1.2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_prefer_server_ciphers&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;include&lt;/span&gt; &lt;span class="s"&gt;enable-php5.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/nginx_status&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;stub_status&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;.*\.(gif|jpg|jpeg|png|bmp|swf)$&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;expires&lt;/span&gt;      &lt;span class="s"&gt;30d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;.*\.(js|css)?$&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;expires&lt;/span&gt;      &lt;span class="s"&gt;12h&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;/.well-known&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;allow&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;/\.&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="kn"&gt;deny&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;if&lt;/span&gt; &lt;span class="s"&gt;(!-e&lt;/span&gt; &lt;span class="nv"&gt;$request_filename&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="kn"&gt;rewrite&lt;/span&gt; &lt;span class="s"&gt;^/(.*)&lt;/span&gt;$ &lt;span class="n"&gt;/index.php?s=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt; &lt;span class="s"&gt;last&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kn"&gt;access_log&lt;/span&gt; &lt;span class="n"&gt;/home/wwwlogs/test001.log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;</description>
      <author>apgeypeu</author>
      <pubDate>Wed, 04 Oct 2017 10:31:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/34320</link>
      <guid>https://ruby-china.org/topics/34320</guid>
    </item>
    <item>
      <title>各位大佬帮忙看个 Nginx 的问题</title>
      <description>&lt;p&gt;各位大佬帮忙看个 Nginx 的问题&lt;/p&gt;

&lt;p&gt;程序前台访问一些内容，然后用 Nginx 的 auth 模块加了一层验证，如果 token 正确就返回 200，错误就返回 401&lt;/p&gt;

&lt;p&gt;但是我这里用前台传过来的&lt;/p&gt;

&lt;p&gt;key:x-auth-token          value:834d4531-035b-475f-96bf-b54b1be2bce0&lt;/p&gt;

&lt;p&gt;让 nginx 往后端传的时候&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2017/0029eb79-3a81-4546-981b-15f3c885b043.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;X-auth-token $http_x-auth-token&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2017/30019303-afc3-41ab-b300-ea6f821cb509.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;后端接到的 value 却变成了 &lt;/p&gt;

&lt;p&gt;key:x-auth-token          value:-auth-token&lt;/p&gt;

&lt;p&gt;求大佬帮忙看看为什么获取不到前台的 x-auth-token 变量&lt;/p&gt;</description>
      <author>xandy5004</author>
      <pubDate>Tue, 26 Sep 2017 21:30:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/34263</link>
      <guid>https://ruby-china.org/topics/34263</guid>
    </item>
    <item>
      <title>Windows 版  request.getScheme () 如何获取 https</title>
      <description>&lt;p&gt;windows 下 nginx-1.12.1 实现 http 转 https。
nginx.conf&lt;/p&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;server&lt;/span&gt; {
       &lt;span class="n"&gt;listen&lt;/span&gt;       &lt;span class="m"&gt;80&lt;/span&gt;;
       &lt;span class="n"&gt;server_name&lt;/span&gt;  *.&lt;span class="n"&gt;cn&lt;/span&gt;;
       &lt;span class="n"&gt;rewrite&lt;/span&gt; ^(.*)$ &lt;span class="n"&gt;https&lt;/span&gt;://$&lt;span class="n"&gt;host&lt;/span&gt;$&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;permanent&lt;/span&gt;;

}
            &lt;span class="n"&gt;proxy_set_header&lt;/span&gt;       &lt;span class="n"&gt;Host&lt;/span&gt; $&lt;span class="n"&gt;host&lt;/span&gt;;  

        &lt;span class="n"&gt;proxy_set_header&lt;/span&gt;  &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Real&lt;/span&gt;-&lt;span class="n"&gt;IP&lt;/span&gt;  $&lt;span class="n"&gt;remote_addr&lt;/span&gt;;  
    &lt;span class="n"&gt;proxy_set_header&lt;/span&gt;  &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;For&lt;/span&gt; $&lt;span class="n"&gt;proxy_add_x_forwarded_for&lt;/span&gt;;  
    &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;Proto&lt;/span&gt; $&lt;span class="n"&gt;scheme&lt;/span&gt;;
    &lt;span class="n"&gt;proxy_set_header&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;-&lt;span class="n"&gt;Forwarded&lt;/span&gt;-&lt;span class="n"&gt;Scheme&lt;/span&gt; $&lt;span class="n"&gt;scheme&lt;/span&gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;tomcat 的 server.xml 增加：&lt;/p&gt;
&lt;pre class="highlight erb"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Valve&lt;/span&gt; &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;"org.apache.catalina.valves.RemoteIpValve"&lt;/span&gt;  
                          &lt;span class="na"&gt;remoteIpHeader=&lt;/span&gt;&lt;span class="s"&gt;"X-Forwarded-For"&lt;/span&gt;  
                          &lt;span class="na"&gt;protocolHeader=&lt;/span&gt;&lt;span class="s"&gt;"X-Forwarded-Proto"&lt;/span&gt;  
                          &lt;span class="na"&gt;protocolHeaderHttpsValue=&lt;/span&gt;&lt;span class="s"&gt;"https"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;jsp 中：String path = request.getContextPath(); String basePath = request.getScheme() + "://"
request.getServerName() + ":" + request.getServerPort()
取到的仍然是 http，不是 https&lt;/p&gt;</description>
      <author>dudm6911</author>
      <pubDate>Mon, 18 Sep 2017 10:11:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/34158</link>
      <guid>https://ruby-china.org/topics/34158</guid>
    </item>
    <item>
      <title>请问各路大侠 nginx 怎么绑定.pro 后缀的域名</title>
      <description>&lt;p&gt;请问各路大侠 nginx 怎么绑定.pro 后缀的域名&lt;/p&gt;</description>
      <author>cison</author>
      <pubDate>Fri, 15 Sep 2017 15:41:25 +0800</pubDate>
      <link>https://ruby-china.org/topics/34140</link>
      <guid>https://ruby-china.org/topics/34140</guid>
    </item>
    <item>
      <title>使用 Nginx 搭建文件下载服务器，但点击下载，响应时间随文件大小变大而增加</title>
      <description>&lt;p&gt;设置如下：&lt;/p&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;server&lt;/span&gt; {
        &lt;span class="n"&gt;listen&lt;/span&gt;   &lt;span class="m"&gt;8110&lt;/span&gt;;
        &lt;span class="n"&gt;server_name&lt;/span&gt;  &lt;span class="n"&gt;localhost&lt;/span&gt;;

        &lt;span class="n"&gt;access_log&lt;/span&gt;  /&lt;span class="n"&gt;root&lt;/span&gt;/&lt;span class="n"&gt;log&lt;/span&gt;;

        &lt;span class="n"&gt;root&lt;/span&gt;    /&lt;span class="n"&gt;pathto&lt;/span&gt;/&lt;span class="n"&gt;dowloads&lt;/span&gt;;

        &lt;span class="n"&gt;autoindex&lt;/span&gt;       &lt;span class="n"&gt;on&lt;/span&gt;;
        &lt;span class="n"&gt;autoindex_exact_size&lt;/span&gt;    &lt;span class="n"&gt;off&lt;/span&gt;;
        &lt;span class="n"&gt;autoindex_localtime&lt;/span&gt;     &lt;span class="n"&gt;on&lt;/span&gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;请问有什么其他设置可以改进体验吗？&lt;/p&gt;

&lt;p&gt;比如：
&lt;a href="https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/" rel="nofollow" target="_blank"&gt;https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/&lt;/a&gt;
这个网站，也是用 nginx 搭建的，点击要下载的文件，马上就跳出下载框了。
然而我的，几十兆的文件都要等半天才会跳出下载框。&lt;/p&gt;

&lt;p&gt;求教。&lt;/p&gt;</description>
      <author>sujielei</author>
      <pubDate>Tue, 22 Aug 2017 17:48:41 +0800</pubDate>
      <link>https://ruby-china.org/topics/33901</link>
      <guid>https://ruby-china.org/topics/33901</guid>
    </item>
    <item>
      <title>为何 Nginx 只有部分域名能进去</title>
      <description>&lt;p&gt;接手到旧后台的服务器，目前只能访问他以前的域名，换回我自己的前缀却不可以，求解
&lt;img src="https://l.ruby-china.com/photo/2017/068f744e-cdd7-415e-9558-e5b2acb3a347.jpg!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2017/b854ae18-dbed-4d30-9cd4-60acedb8b30f.png!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>AgainCheng</author>
      <pubDate>Tue, 22 Aug 2017 11:05:39 +0800</pubDate>
      <link>https://ruby-china.org/topics/33898</link>
      <guid>https://ruby-china.org/topics/33898</guid>
    </item>
    <item>
      <title> 求助正则大神！！！NGINX 静态目录如何仅代理子目录下的文件！？</title>
      <description>&lt;p&gt;如题，有以下应用场景，用 nginx 代理 D 盘下 d:/data 目录，想通过路由，如&lt;a href="http://localhost/data/test.txt" rel="nofollow" target="_blank"&gt;http://localhost/data/test.txt&lt;/a&gt; 去访问 d:/data/20170820/test.txt 这个文件，我的 location 配置应该如何写？要不要用正则？要不要中 rewrite，可是我两者都不熟啊大神们！！！求助 ing&lt;img title=":sweat_smile:" alt="😅" src="https://twemoji.ruby-china.com/2/svg/1f605.svg" class="twemoji"&gt; 
这是静态目录的结构：
&lt;img src="https://l.ruby-china.com/photo/2017/b346a33c-fe43-45db-9607-a63c771acbfc.jpg!large" title="" alt=""&gt;
这是 20170820 目录下文件存放的方式：
&lt;img src="https://l.ruby-china.com/photo/2017/1d803802-96f3-4935-84c3-87c7e6c24c68.jpg!large" title="" alt=""&gt;
求助大神！&lt;/p&gt;</description>
      <author>a814503592</author>
      <pubDate>Sun, 20 Aug 2017 10:57:18 +0800</pubDate>
      <link>https://ruby-china.org/topics/33885</link>
      <guid>https://ruby-china.org/topics/33885</guid>
    </item>
  </channel>
</rss>
