htaccess重定向基于查询参数值

时间:2017-08-14 16:27:48

标签: apache .htaccess redirect mod-rewrite apache2.2

我的应用程序曾经使用lang.php文件进行语言切换。 /path/to/page.php?foo=bar重定向到英语的网址如下所示:

/path/to/lang.php?lang=en-CA&uri=%2Fpath%2Fto%2Fpage.php%3Ffoo%3Dbar

最近,在所有网页上都接受了lang查询参数的一些更改。所以这个URL更好:

/path/to/page.php?foo=bar&lang=en-CA

我希望能够将.htaccess文件添加到我拥有lang.php文件的所有位置,以便在没有lang.php文件的情况下保持现有网址的正常运行。这可能吗?

当应用程序在不同的主机名和路径上运行时,RewriteRules必须与lang.php完全相关。

我根据the answer here对它进行了抨击,但这给了我一个404:

RewriteCond %{REQUEST_FILENAME} lang.php$
RewriteCond %{QUERY_STRING} (?:^|&)uri=([^&]+) [NC]
RewriteRule lang.php - [E=LANG_REDIR_URI:%1]

RewriteCond %{REQUEST_FILENAME} lang.php$
RewriteCond %{QUERY_STRING} (?:^|&)lang=([^&]+) [NC]
RewriteRule lang.php - [E=LANG_REDIR_LANG:%1]

RewriteCond %{REQUEST_FILENAME} lang.php$
RewriteRule . %{LANG_REDIR_URI}e [L,R=temporary]

uri参数可能已经有查询参数(如上面的例子所示),代码不应该使应用程序容易受到open redirect vulnerability的攻击。<​​/ p>

不同的情况:

  • 包含查询字符串的URI,首先是lang:/foo/bar/lang.php?lang=en-CA&uri=%2Ffoo%2Fbar%2Fpage.php%3Fid%3D123应重定向到/foo/bar/page.php?id=123&lang=en-CA
  • 没有查询字符串的URI,首先是lang:/foo/bar/lang.php?lang=en-CA&uri=%2Ffoo%2Fbar%2Fpage.php应重定向到/foo/bar/page.php?lang=en-CA
  • 包含查询字符串的URI,首先是uri:/foo/bar/lang.php?uri=%2Ffoo%2Fbar%2Fpage.php%3Fid%3D123&lang=en-CA应重定向到/foo/bar/page.php?id=123&lang=en-CA
  • 没有查询字符串的URI,首先是uri:/foo/bar/lang.php?uri=%2Ffoo%2Fbar%2Fpage.php&lang=en-CA应该重定向到/foo/bar/page.php?lang=en-CA

查询参数的顺序在重定向目标中无关紧要。

更新

https://stackoverflow.com/a/45732670/404623提供初步答案后,我尝试了以下.htaccess规则:

# This only works for uri values without query strings

RewriteCond %{QUERY_STRING} ^(lang=[^&]+)&uri=([^&]+) [NC]
RewriteRule lang\.php$ /%2\?%1 [L,NE,R=temporary]
RewriteCond %{QUERY_STRING} ^uri=([^&]+)&(lang=[^&]+) [NC]
RewriteRule lang\.php$ /%1\?%2 [L,NE,R=temporary]

# This only works for uri values with query strings

RewriteCond %{QUERY_STRING} ^(lang=[^&]+)&uri=([^&]+) [NC]
RewriteRule lang\.php$ /%2&%1? [L,NE,R=temporary]
RewriteCond %{QUERY_STRING} ^uri=([^&]+)&(lang=[^&]+) [NC]
RewriteRule lang\.php$ /%1&%2? [L,NE,R=temporary]

1 个答案:

答案 0 :(得分:0)

您可以在RewriteEngine On行下方的网站根.htaccess中使用此规则:

RewriteEngine On

# uri with query string    
RewriteCond %{QUERY_STRING}     (?:^|&)(lang=[^&]+) [NC]
RewriteCond %1##%{QUERY_STRING} (.*)##(?:.*&)?uri=([^?]+)(?:\?|%3F)([^&]+) [NC]
RewriteRule lang\.php$ /%2?%1&%3 [L,NE,R=302]

# uri without query string    
RewriteCond %{QUERY_STRING}     (?:^|&)(lang=[^&]+) [NC]
RewriteCond %1##%{QUERY_STRING} (.*)##(?:.*&)?uri=([^?]+) [NC]
RewriteRule lang\.php$ /%2?%1 [L,NE,R=302]