在 or 中简单的使用cookies 复杂的操作请使用
[lua_resty_cookies]
(https://github.com/cloudflare/lua-resty-cookie)
基本操作
<code class="hljs perl has-numbering"><span class="hljs-keyword">local</span> cookie_name = <span class="hljs-string">"cookie_session"</span> ngx.<span class="hljs-keyword">say</span>(ngx.var[cookie_name])</code>
- 设置 cookies
<code class="hljs avrasm has-numbering">ngx<span class="hljs-preprocessor">.header</span>[<span class="hljs-string">"Set-Cookie"</span>] = <span class="hljs-string">"session=af54; Path=/; Expires="</span> .. ngx<span class="hljs-preprocessor">.cookie</span>_time(ngx<span class="hljs-preprocessor">.time</span>() + <span class="hljs-number">86400</span>)</code>
测试代码
<code class="hljs avrasm has-numbering"> location ~ /header_add { content_by_lua_block { ngx<span class="hljs-preprocessor">.header</span>[<span class="hljs-string">"Set-Cookie"</span>] = <span class="hljs-string">"session=lzz; Path=/; Expires="</span> .. ngx<span class="hljs-preprocessor">.cookie</span>_time(ngx<span class="hljs-preprocessor">.time</span>() + <span class="hljs-number">86400</span>) ngx<span class="hljs-preprocessor">.say</span>(<span class="hljs-string">"orangleliu"</span>) } }</code>
看看效果
<code class="hljs avrasm has-numbering"><span class="hljs-preprocessor"># curl -i 127.0.0.1:8001/header_add</span> HTTP/<span class="hljs-number">1.1</span> <span class="hljs-number">200</span> OK <span class="hljs-label">Server:</span> openresty/<span class="hljs-number">1.9</span><span class="hljs-number">.7</span><span class="hljs-number">.1</span> <span class="hljs-label">Date:</span> Fri, <span class="hljs-number">16</span> <span class="hljs-keyword">Dec</span> <span class="hljs-number">2016</span> <span class="hljs-number">07</span>:<span class="hljs-number">00</span>:<span class="hljs-number">30</span> GMT Content-Type: text/html Transfer-Encoding: chunked <span class="hljs-label">Connection:</span> keep-alive <span class="hljs-keyword">Set</span>-Cookie: session=lzz<span class="hljs-comment">; Path=/; Expires=Sat, 17-Dec-16 07:00:30 GMT</span></code>
- set cookie 使用的是直接操作 header 的方式,这个时候如果单独添加一个 cookie 就会覆盖掉其他的值,所以需要多做一些处理。
<code class="hljs lua has-numbering"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get_<a href="https://www.lushuiwan.com/tag/cookies" title="查看更多关于 cookies 的文章" target="_blank">cookies</a></span><span class="hljs-params">()</span></span> <span class="hljs-keyword">local</span> cookies = ngx.header[<span class="hljs-string">"Set-Cookie"</span>] <span class="hljs-keyword">or</span> {} <span class="hljs-keyword">if</span> <span class="hljs-built_in">type</span>(cookies) == <span class="hljs-string">"string"</span> <span class="hljs-keyword">then</span> cookies = {cookies} <span class="hljs-keyword">end</span> <span class="hljs-keyword">return</span> cookies <span class="hljs-keyword">end</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add_cookie</span><span class="hljs-params">(cookie)</span></span> <span class="hljs-keyword">local</span> cookies = get_cookies() <span class="hljs-built_in">table</span>.insert(cookies, cookie) ngx.header[<span class="hljs-string">'Set-Cookie'</span>] = cookies <span class="hljs-keyword">end</span> add_cookie(<span class="hljs-string">"session=aff12d; Path=/"</span>)</code>
⚠️:上面的代码需要在 header_filter
阶段运行,在这个阶段可以获取 应用或者是后端 proxy 设置的 cookies, 如果你想要 添加,删除,替换某一个 cookies,注意不要覆盖所有的 cookies 了。
- 删除 cookies 跟上面类似
一个例子,在 content 阶段设置了多个 cookies,然后在 header_filter
阶段删除 cookies
<code class="hljs livecodeserver has-numbering"> location ~ /header_delete { content_by_lua_block { ngx.header[<span class="hljs-string">"Set-Cookie"</span>] = {<span class="hljs-string">'Foo=abc; path=/'</span>, <span class="hljs-string">'age=18; path=/'</span>} ngx.say(<span class="hljs-string">"openresty"</span>) } header_filter_by_lua_block { <span class="hljs-built_in">local</span> match = <span class="hljs-keyword">string</span>.match <span class="hljs-built_in">local</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">get_cookies</span>()</span> <span class="hljs-comment">-- local cookies = ngx.header["Set-Cookie"] or {}</span> <span class="hljs-built_in">local</span> cookies = ngx.header.set_cookie <span class="hljs-operator">or</span> {} <span class="hljs-keyword">if</span> type(cookies) == <span class="hljs-string">"string"</span> <span class="hljs-keyword">then</span> cookies = {cookies} <span class="hljs-function"><span class="hljs-keyword">end</span></span> <span class="hljs-constant">return</span> cookies <span class="hljs-function"><span class="hljs-keyword">end</span></span> <span class="hljs-built_in">local</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">remove_cookie</span>(<span class="hljs-title">cookie_name</span>)</span> <span class="hljs-built_in">local</span> cookies = get_cookies() ngx.<span class="hljs-built_in">log</span>(ngx.ERR, <span class="hljs-string">"source cookies "</span>, table.concat(cookies, <span class="hljs-string">" "</span>)) <span class="hljs-keyword">for</span> key, <span class="hljs-built_in">value</span> <span class="hljs-operator">in</span> ipairs(cookies) <span class="hljs-built_in">do</span> <span class="hljs-built_in">local</span> name = match(<span class="hljs-built_in">value</span>, <span class="hljs-string">"(.-)="</span>) ngx.<span class="hljs-built_in">log</span>(ngx.ERR, key..<span class="hljs-string">"<=>"</span>, <span class="hljs-built_in">value</span>) <span class="hljs-keyword">if</span> name == cookie_name <span class="hljs-keyword">then</span> table.remove(cookies, key) <span class="hljs-function"><span class="hljs-keyword">end</span></span> <span class="hljs-function"><span class="hljs-keyword">end</span></span> ngx.header[<span class="hljs-string">'Set-Cookie'</span>] = cookies <span class="hljs-operator">or</span> {} ngx.<span class="hljs-built_in">log</span>(ngx.ERR, <span class="hljs-string">"new cookies "</span>, table.concat(cookies, <span class="hljs-string">" "</span>)) <span class="hljs-function"><span class="hljs-keyword">end</span></span> remove_cookie(<span class="hljs-string">"Foo"</span>) } } }</code>
测试下
<code class="hljs avrasm has-numbering"><span class="hljs-preprocessor"># curl '127.0.0.1:8001/header_delete' -i</span> HTTP/<span class="hljs-number">1.1</span> <span class="hljs-number">200</span> OK <span class="hljs-label">Server:</span> openresty/<span class="hljs-number">1.9</span><span class="hljs-number">.7</span><span class="hljs-number">.1</span> <span class="hljs-label">Date:</span> Fri, <span class="hljs-number">16</span> <span class="hljs-keyword">Dec</span> <span class="hljs-number">2016</span> <span class="hljs-number">08</span>:<span class="hljs-number">07</span>:<span class="hljs-number">34</span> GMT Content-Type: text/html Transfer-Encoding: chunked <span class="hljs-label">Connection:</span> keep-alive <span class="hljs-keyword">Set</span>-Cookie: age=<span class="hljs-number">18</span><span class="hljs-comment">; path=/</span></code>
其他需求
- 在做 proxy_pass 之后想给请求统一修改 cookies 值这么做呢?反正都很类似了。。
使用 header_filter_by_lua
指令
<code class="hljs applescript has-numbering">header_filter_by_lua ' <span class="hljs-keyword">local</span> cookies = ngx.header.set_cookie <span class="hljs-keyword">if</span> cookies <span class="hljs-keyword">then</span> <span class="hljs-keyword">if</span> type(cookies) ~= <span class="hljs-string">"table"</span> <span class="hljs-keyword">then</span> cookies = {cookies} <span class="hljs-keyword">end</span> <span class="hljs-keyword">local</span> gsub = <span class="hljs-type">string</span>.gsub <span class="hljs-keyword">local</span> changed <span class="hljs-keyword">for</span> i, cookie <span class="hljs-keyword">in</span> ipairs(cookies) do <span class="hljs-keyword">local</span> new_cookie = gsub(cookie, <span class="hljs-string">"^target%-cookie=[^;]*"</span>, <span class="hljs-string">"target-cookie=myvalue"</span>, <span class="hljs-number">1</span>) <span class="hljs-keyword">if</span> new_cookie ~= cookie <span class="hljs-keyword">then</span> cookies[i] = new_cookie changed = <span class="hljs-constant">true</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> <span class="hljs-keyword">if</span> changed <span class="hljs-keyword">then</span> ngx.header.set_cookie = cookies <span class="hljs-keyword">end</span> <span class="hljs-keyword">end</span> ';</code>
https://github.com/openresty/headers-more-nginx-module/issues/18