• -------------------------------------------------------------
  • ====================================

OpenResty 操作cookies

大数据库 dewbay 7年前 (2018-05-22) 2413次浏览 已收录 0个评论 扫描二维码

在 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>
<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

ref


露水湾 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:OpenResty 操作cookies
喜欢 (0)
[]
分享 (0)
关于作者:
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址