Лак аутентифицирует кешированный запрос
У меня есть частный веб-сайт в стиле интранет, где каждый должен войти в систему, чтобы увидеть какой-либо контент После того, как они вошли в систему, все страницы одинаковы - поэтому я хочу, чтобы эти страницы кэшировались в Varnish, но все же с быстрой проверкой доступа пользователя.
Так что я думал сделать это, я бы создал правило в моем файле VCL, которое переписывает каждый входящий запрос в один файл. Этот файл не кэшируется и проверяет, является ли пользователь действительным, если это так, он печатает включенное в кэш страницу.
Это все хорошо, за исключением идентификации второго запроса для кэшированной страницы как аутентифицируемого. Я думал о добавлении строки запроса к запросу и проверке этого. Или, может быть, есть способ проверить, был ли сделан запрос через esi: include. Возможно, я подхожу к этому неправильно?
Какие-либо предложения?
3 ответа
Если вы не хотите использовать аутентифицированный запрос с токеном аутентификации в URL, вы можете проверить req.esi_level и убедиться, что он больше 0 для ресурсов, требующих входа в систему.
if (req.esi_level == 0 && req.url ~ "^/private/.*" ) {
error (403);
}
Предостережение заключается в том, что вам нужно запретить доступ к своему бэкэнду из всего, кроме лака - что вы, вероятно, в любом случае делаете, но это стоит отметить.
Вот то, что я попробовал в dev env, я еще не уверен, будем ли мы использовать это в производстве.
Лак конфиг
probe checkslash {
.url = "/robots.txt";
.interval = 500s;
.timeout = 10s;
}
include "backends.vcl";
/** generic config from here down */
sub vcl_recv{
/* if the drupals are down, this is how long we cache for */
set req.grace = 6h;
/* Make sure we direct 443 traffic to the secure drupal */
if (server.port == 443 ) {
set req.backend = drpau_ssl_director;
} else {
/* port 80 traffic goes to the correct LB */
set req.backend = drpau_director;
}
# just pass through non-page files, and the login page
if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js|htc|ejs)(\?.*)?$") {
} else if (req.url ~ "(?i)(sites/default/files)|(js/)|(/login)" ) {
} else if (req.esi_level == 0 ) {
# pass regular pages to a spoecial url
set req.url = "/esi" + req.url;
}
return (lookup);
}
sub vcl_fetch {
if (req.url ~ "/esi/" && req.esi_level == 0 ) {
set beresp.do_esi = true; /* Do ESI processing */
}
}
Затем в Apache я перенаправить все запросы на страницы, которые приходят через префикс ESI
RewriteRule ^esi/(.*)$ test.php [L]
и проверить php
<?php
define('DRUPAL_ROOT', getcwd());
// We prepare only a minimal bootstrap.
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
global $user;
$roles = user_roles();
if (in_array('anonymous user', $user->roles)) {
$uri = preg_replace('#^/esi#', '', $_SERVER[REQUEST_URI]);
echo "<esi:include src=\"http://$_SERVER[SERVER_NAME]$uri\"/>";
} else {
header("Location: https://$_SERVER[SERVER_NAME]/login");
}
Если вам нужна только базовая проверка подлинности, вы можете использовать обычную HTTP-аутентификацию, как описано на http://blog.tenya.me/blog/2011/12/14/varnish-http-authentication/:
Пользователь: пропуск
$echo -n "foo:bar" | base64
VCL
sub vcl_fetch {
# ...
if (! req.http.Authorization ~ "Basic Zm9vOmJhcgo=")
{
error 401 "Restricted";
}
# ...
}
sub vcl_error {
# ...
if (obj.status == 401) {
set obj.http.Content-Type = "text/html; charset=utf-8";
set obj.http.WWW-Authenticate = "Basic realm=Secured";
synthetic {"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML>
<HEAD>
<TITLE>Error</TITLE>
<META HTTP-EQUIV='Content-Type' CONTENT='text/html;'>
</HEAD>
<BODY><H1>401 Unauthorized (varnish)</H1></BODY>
</HTML>
"};
return (deliver);
}
# ...
}
Если вы предпочитаете текущий подход, вы всегда можете установить cookie-файл по первому запросу, а затем проверить, есть ли cookie-файл.