删除某些查询字符串参数,除非它是通过重写添加的

Remove certain query string parameter UNLESS it was added by rewrite

使用 .htaccess 我想将 %{PATH_INFO} 变成 bootstrapping 的查询字符串参数。但是我想防止访问者手动输入bootstrap参数。

所以这个输入了URL: www.example.com/user/pictures?id=65

实际显示: www.example.com?bootstrap=/user/pictures&id=65

但如果手动输入

这个进入URL:www.example.com?bootstrap=/user/pictures&id=65

删除它: www.example.com?id=65

或显示错误: 404:not found

最佳情况

手动输入的 bootstrap 被忽略并且 %{PATH_INFO} 成为新参数。

所以这个: www.example.com/user/pictures?id=65&bootstrap=somecrap

显示: www.example.com?id=65&bootstrap=/user/pictures

阻止手动输入的 bootstrap 参数有两个原因。 1)安全。我们不希望用户寻找和啄食不打算显示的文件。 2)冲突。我们不想在手动输入的 bootstrap 和正确的 %{PATH_INFO} 之间做出选择。

删除 bootstrap 参数很容易。像...

RewriteCond %{QUERY_STRING} ^(.*&)?bootstrap=[^&]*(?:&(.*))?$ [NC]
RewriteRule ^ %{REQUEST_URI}?%1%2 [L,NE]

添加参数很容易。 (我的比较复杂,但这说明了这个想法。)

 RewriteCond %{REQUEST_FILENAME} -f
 RewriteCond %{REQUEST_URI}%{PATH_INFO} (.*?)(/.+)$
 RewriteRule ^(.*)$ /%1?bootstrap=%2 [QSA,L]

如果 htaccess 只 运行 通过一次,那两个片段就可以了。但是,htaccess 在每次重写后都会重新启动,并且我添加的 bootstrap 参数会再次被删除。

我知道快速解决方法是将 [END] 添加到第二条规则,但这在这里行不通。

我需要的是一种方法来删除 ?"bootstrap=xxx" 仅从原始请求中而不是从重写的请求中删除。

谢谢

这样做的方法是在成功重写时设置一个环境变量,您可以使用 E 标志来完成。所以像这样:

RewriteRule ^example$ ?param=example [E=rewritten:1]

然后您可以在以下条件下检查它:

RewriteCond %{ENV:rewritten} !=1

或者:

RewriteCond %{ENV:rewritten} =1

但是,在 .htaccess 中使用它时必须小心,因为如果完成 .htaccess 文件的传递并生成内部重定向,生成的任何环境变量都将 REDIRECT_ 放在他们前面。因此,对于后续通过,在大多数情况下,您还需要检查它,或者仅为此检查,如果您的规则高于您添加环境变量的位置:

RewriteCond %{ENV:REDIRECT_rewritten} !=1

或者:

RewriteCond %{ENV:REDIRECT_rewritten} =1

参考:

要识别这是否是原始请求,您可以检查某些 REDIRECT_ 变量

REDIRECT_ environment variables are created from the environment variables which existed prior to the redirect. They are renamed with a REDIRECT_ prefix, i.e., HTTP_USER_AGENT becomes REDIRECT_HTTP_USER_AGENT.

REDIRECT_URL, REDIRECT_STATUS, and REDIRECT_QUERY_STRING are guaranteed to be set, and the other headers will be set only if they existed prior to the error condition.

因此,对于您的情况,您可以检查 REDIRECT_STATUSREDIRECT_QUERY_STRING 以查看这是外部请求还是内部请求。

仅删除 bootstrap=,如果这是一个外部请求,即 REDIRECT_QUERY_STRING 为空

RewriteCond %{REDIRECT_QUERY_STRING} ^$
RewriteCond %{QUERY_STRING} ^(.*&)?bootstrap=[^&]*(?:&(.*))?$ [NC]
RewriteRule ^ %{REQUEST_URI}?%1%2 [L,NE]

另一种方法类似,但现在检查变量是否为空,例如

RewriteCond %{REDIRECT_QUERY_STRING} .
RewriteCond %{QUERY_STRING} ^(.*&)?bootstrap=[^&]*(?:&(.*))?$ [NC]
RewriteRule ^ %{REQUEST_URI}?%1%2 [L,NE]

如果合适,您还可以检查特定值。