因此,在整个社区中寻找解决方案后,我的问题如下:
我在Wordpress环境中的Apache服务器中工作。我在上传文件中有一个名为/restricted/
的文件夹。此处的所有内容(任何文件扩展名)仅在以下情况下可访问:
如果这些条件失败,则将提供图像。在这个/restricted/
文件夹中,我得到了一个.htaccess
文件。一切都必须(最好)在该htaccess文件中完成,而不是不在根 htaccess文件中。
cookie是由functions.php设置的,这没问题 部分。关于安全性的评论不是这里的问题
这是一个网址示例(本地主机):http://localhost/komfortkonsult/wp-content/uploads/restricted/some-file.jpg?r=870603c9d23f2b7ea7882e89923582d7
第一个条件设置了一个名为custom_cookie的cookie ,一切正在使用:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /komfortkonsult/
RewriteCond %{REQUEST_URI} ^.*uploads/restricted/.*
RewriteCond %{HTTP_COOKIE} !custom_cookie
RewriteRule . /komfortkonsult/restricted.png [R,L]
</IfModule>
但是,下一部分是我 完全是蓝色的 ,但是我尝试失败了,以下方法:
RewriteCond %{HTTP_COOKIE} custom_cookie=(.*)$
RewriteCond %1::%{REQUEST_URI} ^(.*?)::/\1/?
RewriteRule . /komfortkonsult/restricted.png [R,L]
类似:
RewriteCond %{QUERY_STRING} ^r=(.*)$
RewriteRule ^/ - [E=COOKIE_MATCH:%1]
RewriteCond %{HTTP_COOKIE} !custom_cookie="%{ENV:COOKIE_MATCH}"
RewriteRule . /komfortkonsult/restricted.png [R,L]
类似:
RewriteCond %{HTTP_COOKIE} custom_cookie=([^;]+) [NC]
RewriteCond %{REQUEST_URI} !%1 [NC]
RewriteRule . /komfortkonsult/restricted.png [R,L]
以此类推。我真的想将其保留在.htaccess
内,而不是通过.php
文件调用使用验证。但是如果这是我的体系结构的唯一解决方案,请提供完整的示例(不是foo = bar,您的重定向将在此处...)
欢迎使用其他实现我目标的方法。
非常感谢您帮助我解决这个问题。
/ Intervik
更新(在接受答案并生效之后)使用示例
目标是在单个Wordpress安装中实现一层保护。 隐藏的所有媒体,图像或其他文件,并附加到页面上, (由图像替换)(如果 A),用户未登录或 B)用户已登录,但不能具有'edit_post'功能。
但是限制仅适用于上传到名为/restricted/
的唯一文件夹中的文件。该文件夹位于Wordpress原始/uploads/
根目录中。该受限材料不允许被搜索引擎等直接链接或访问。不允许浏览器缓存,并且注销后必须立即进行限制。还有更多...但是我想你明白了。
名称空间'custom_cookie'
仅是一个示例。显示Wordpress安装的示例位于localhost的子文件夹中。像h**p://example.com/workspace/
。如果是根用户,请删除'workspace/'
。
cookie体系结构functions.php
function intervik_theme_set_custom_cookie(){
if(is_user_logged_in()){
global $current_user;
if(current_user_can('edit_posts')){
if(!isset($_COOKIE['custom_cookie'])){
$cookie_value = $current_user->ID . '|' . $current_user->user_login . '|' . $current_user->roles;
$salt = wp_salt('auth');
$cookie_hash = hash_hmac('md5', $cookie_value, $salt);
setcookie('custom_cookie', $cookie_hash, time()+36, '/');
$_COOKIE['custom_cookie'] = $cookie_hash;
} else {
$cookie_value = $current_user->ID . '|' . $current_user->user_login . '|' . $current_user->roles;
$salt = wp_salt('auth');
$cookie_hash = hash_hmac('md5', $cookie_value, $salt);
if($cookie_hash != $_COOKIE['custom_cookie']){
setcookie('custom_cookie', '', 1, '/');
unset($_COOKIE['custom_cookie']);
}
}
} else {
if(isset($_COOKIE['custom_cookie'])){
setcookie('custom_cookie', '', 1, '/');
unset($_COOKIE['custom_cookie']);
}
}
} else {
if(isset($_COOKIE['custom_cookie'])){
setcookie('custom_cookie', '', 1, '/');
unset($_COOKIE['custom_cookie']);
}
}
}
add_action('init', 'intervik_theme_set_custom_cookie');
如您所见,在每个+36秒的时间内,每个Cookie 对于每个有效用户都是唯一的(足以加载页面-但使用+120可以2分钟)。此“令牌”适用于发送到服务器的每个请求:
附件网址过滤器的链接:
function intervik_restricted_wp_get_attachment_url($url, $post_id){
if(strpos($url, '/restricted/') !== FALSE){
if(isset($_COOKIE['custom_cookie'])){
$url = add_query_arg('r', $_COOKIE['custom_cookie'], $url);
}
}
return $url;
}
add_filter('wp_get_attachment_url', 'intervik_restricted_wp_get_attachment_url', 10, 2);
我们不允许任何其他查询字符串。备注,必须为大小添加更多过滤器,例如wp_get_attachment_image_src
等。但是直接链接到媒体就足够了。
将
跳过管理后端中的过滤器if(current_user_can('edit_posts')
替换为另一个if(is_user_logged_in() ...
将所有内容更改为仅登录/注销 用户。然后使用if(!is_admin() && strpos($url, '/restricted/')!== FALSE) ...
最后是.htaccess
文件夹根目录中的uploads/restricted/
文件:
# BEGIN Intervik
Options +FollowSymLinks
Options All -Indexes
<IfModule !mod_rewrite.c>
Deny from all
</IfModule>
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</IfModule>
RewriteEngine On
RewriteCond %{HTTP_COOKIE}::%{QUERY_STRING} !\bcustom_cookie=([0-9a-f]{32})\b.*::r=\1(&|$)
RewriteRule . /workspace/restricted.png? [R,L]
# END Intervik
我还在Wordpress安装根目录中放置了漂亮的PNG IMAGE“限制访问超时”。对于无效的管理员,这也可用作“库管理”区域中的缩略图。上传过滤器或后端是另一个区域。
我们不是在这里保护英格兰的财务计划,但我们想保留 从Google和其他一些组织那里拿走一些文件给组织和一些照片 你的妻子。
请发表评论
它确实有效,欢迎您评论这些缺陷或安全风险。但是,在我们的安装过程中,还需要在该层之上进行PHP的另一层验证,但是对于不太重要的内容,我们需要速度。
答案 0 :(得分:2)
您在进行不同的尝试时会得到一些正确的信息,但是您需要以正确的顺序将它们组合在一起。
请尝试以下操作:
RewriteEngine On
# custom_cookie value is 32 char hex and must match the value of the "r" URL parameter
RewriteCond %{HTTP_COOKIE}::%{QUERY_STRING} !\bcustom_cookie=([0-9a-f]{32})\b.*::r=\1(&|$)
RewriteRule ^ /komfortkonsult/restricted.png [QSD,R,L]
需要QSD
标志(Apache 2.4+)才能从重定向的URL中删除查询字符串。另外,如果您仍在使用Apache 2.2,则可以将?
附加到 susbstitution 。
请注意,此处不需要RewriteBase
。 <IfModule>
也应删除。 <IfModule mod_rewrite.c>
包装器仅在打算在没有mod_rewrite可用的情况下起作用时才需要。它不是。如果mod_rewrite不可用,则您的条件将仅静默失败,并且访问将不受限制。在这种情况下,最好是由于错误而失败,并且禁止访问(所有人)。
假设:
r
URL参数始终是 first URL参数(如您的示例)。您提到了“任何文件扩展名”,但是,仅当首先请求图像时,才真正重定向到图像。如果您有图像以外的文件,最好返回403 Forbidden。 (严格来说,发送403是正确的响应,而不是302,然后是200 OK。)要发送403,只需将RewriteRule
伪指令更改为:
RewriteRule ^ - [F]
这是如何工作的...
除了一个示例之外,所有示例均未提及的重要一点是r
URL参数是查询字符串的一部分,而不是URL路径。 REQUEST_URI
服务器变量仅包含URL路径,特别是不包含查询字符串。要匹配查询字符串,您需要与QUERY_STRING
服务器变量进行比较。
%{HTTP_COOKIE}::%{QUERY_STRING}
-使用确保不会出现的分隔符(cookie
),将::
HTTP请求标头与查询字符串连接在一起无论哪种值。这形成了 TestString 。
!\bcustom_cookie=([0-9a-f]{32})\b.*::r=\1(&|$)
-这是与 TestString 匹配的 CondPattern 。 \b
是一个单词边界,因此我们仅匹配此特定的cookie。此Cookie的值是使用([0-9a-f]{32})
捕获的。然后,我们跳过cookie标头中的所有剩余字符,直到到达分隔符(::
)。之后,我们将与查询字符串( TestString 中的QUERY_STRING
服务器变量的值)进行匹配。 “魔术”是对第一个捕获组的\1
后向引用,即。 Cookie值。
CondPattern 上的!
前缀使整个模式无效。因此,当此模式不匹配时,即条件成功。 Cookie和URL参数的值不同(或根本不存在)。
为什么您的尝试不起作用...
RewriteCond %{HTTP_COOKIE} custom_cookie=(.*)$ RewriteCond %1::%{REQUEST_URI} ^(.*?)::/\1/?
Cookie
标头中的最后一个cookie。这很难保证。REQUEST_URI
)匹配,因此永远不会匹配。假定您的URL格式为:http://localhost/870603c9d23f2b7ea7882e89923582d7
。RewriteCond %{QUERY_STRING} ^r=(.*)$ RewriteRule ^/ - [E=COOKIE_MATCH:%1] RewriteCond %{HTTP_COOKIE} !custom_cookie="%{ENV:COOKIE_MATCH}"
好,您正在检查查询字符串中的URL参数值。但是...
RewriteRule
永远不会匹配,因为URL路径永远不会在每个目录(.htaccess
)上下文中以斜杠开头。因此,永远不会设置COOKIE_MATCH
环境变量。%{ENV:COOKIE_MATCH}
-它被视为文字字符串。您还用双引号将其括起来,它们也不是cookie值的一部分。RewriteCond %{HTTP_COOKIE} custom_cookie=([^;]+) [NC] RewriteCond %{REQUEST_URI} !%1 [NC]
%1
后向引用,因此无论如何这都被视为文字字符串。这就是为什么在 CondPattern 中不评估%{VARIABLE}
(和%1
等)表达式的原因,我们需要使用看似复杂的表达式,该表达式使用的正则表达式反向引用表格:
%{VAR1}@@%{VAR2} ^(.+)@@\1$