nginx location 块捕获一个值并设置cookie,如果它不为空,则重定向到新的URL

Posted

技术标签:

【中文标题】nginx location 块捕获一个值并设置cookie,如果它不为空,则重定向到新的URL【英文标题】:nginx location block capturing a value and setting cookie if it's not empty, redirect to new URL 【发布时间】:2018-12-04 23:12:19 【问题描述】:

很难在标题中概括... 我正在尝试创建一个将指定值保存到 cookie 的 URL,然后重定向用户以摆脱 URL 中的值。

愿望:

domain.com/importantpage => 重定向到importantpage.php(不要修改cookie!)

domain.com/importantpage/ => 重定向到importantpage.php(不要修改cookie!)这个不重要,但会很好

domain.com/importantpage/aSECRETvalue33 => 将secret_code cookie 设置为aSECRETvalue33 并重定向到importantpage.php

我目前写的:

location ~ ^/importantpage/?(.*?)$ 
    add_header Set-Cookie "secret_code=$1;Domain=$server_name;Path=/;Max-Age=31536000;Secure;HTTPOnly" always;
    return 307 $scheme://$server_name/importantpage.php;

这还不够好,因为 domain.com/importantpage(带或不带斜线)将 cookie 设置为空白值。我希望用户能够导航到 domain.com/importantpage 并让它读取现有的 cookie(如果已提供)。

我曾想过在两个地方分开,像这样:

location ~ ^/importantpage$ 
    return 307 $scheme://$server_name/importantpage.php;


location ~ ^/importantpage/(.*?)$ 
    add_header Set-Cookie "secret_code=$1;Domain=$server_name;Path=/;Max-Age=31536000;Secure;HTTPOnly" always;
    return 307 $scheme://$server_name/importantpage.php;

但出于某种我不确定的原因……它不像我想象的那样工作。理论上,第一个应该只由 domain.com/importantpage 调用并避免设置 cookie.. 但是如果提供 / (有或没有值),则应该调用第二个......但是当我导航到 domain.com/importantpage 它仍然设置一个空白值的 cookie?即使第二个需要一个斜杠来匹配它?也许幕后正在发生一些不明显的事情。

有人有什么想法吗?也许有一种方法可以强制正则表达式匹配 1 个或多个非空白字符,或者 IF 语句仅在值不为空白时调用 setcookie?

【问题讨论】:

【参考方案1】:

在单块 sn-p 中,^/importantpage/?(.*?)$ 匹配 /importantpage,后跟零个或一个斜杠,后跟零个或多个字符,然后是输入的结尾,所以 it matches /importantpage/aSECRETvalue33, /importantpage, and /importantpageisnothere/some/other/path。请注意,.*? 类似于.*(任何字符的零个或多个),但匹配非贪婪,在这种情况下这是不必要的,因为您允许跟随它的唯一字符是输入的结尾。

在双块 sn-p 中,因为两者都是非精确前缀,nginx looks for the longest match。您可以改为将块分隔为完全匹配和前缀匹配:

location = /importantpage 
    return 307 $scheme://$server_name/importantpage.php;


location = /importantpage/ 
    return 307 $scheme://$server_name/importantpage.php;


location ~ ^/importantpage/(.+)$ 
    add_header Set-Cookie "secret_code=$1;Domain=$server_name;Path=/;Max-Age=31536000;Secure;HTTPOnly" always;
    return 307 $scheme://$server_name/importantpage.php;

或者您只能通过将正则表达式修复为仅在/ 后面有字符时才匹配来处理第二种情况:

location ~ ^/importantpage/(.+)$ 
    add_header Set-Cookie "secret_code=$1;Domain=$server_name;Path=/;Max-Age=31536000;Secure;HTTPOnly" always;
    return 307 $scheme://$server_name/importantpage.php;

【讨论】:

谢谢!这很好用,但更重要的是感谢您提供了详细的解释。

以上是关于nginx location 块捕获一个值并设置cookie,如果它不为空,则重定向到新的URL的主要内容,如果未能解决你的问题,请参考以下文章

Nginx配置详解

Nginx

Linux下玩转nginx系列——nginx配置文件说明

Linux下玩转nginx系列——nginx配置文件说明

[后端]nginx配置文件详解

Nginx Location 指令语法解析