如果未设置同意 Cookie,Nginx 将重定向到 Cookie 同意页面

Nginx Redirect to Cookie-Consent Page if Consent Cookie not Set

这个问题几乎和this question相反。由于 nginx 只允许 if 并且在 if 子句中只有 returnrewriteproxy_pass 等,但是 try_files 和 [=不能使用 17=] 或 NOT

所以问题是:我想模拟以下内容(在伪 nginx 配置中)

location / {
  if (NOT  isset(cookie("cookie-consent")) ) {
    return 302 "https://example.com/cookieconsent";
  }
  else {
    # I am running the site on a backend server
    proxy_pass https://example.com:8443;
  }
}

# The HTML here has a button to agree to the use of said cookies
location /cookieconsent {
  root /path/to/www-root;
  try_files $uri/index.html $uri.html;
}

location /setconsent {
  add_header Set-Cookie 'consent=true;Domain=$host;Path=/;Max-Age=7776000;SameSite=strict;HTTPOnly;Secure';
  return 302 https://$host;
}

这件事的背景是我正在使用 Nextcloud 并且由于 Nextcloud 仅使用功能性 cookie,因此通过弹出窗口通知用户使用 cookie 就足够了,但是 Nextcloud 没有 GDPR Cookie 同意插件,也不是我很想开发一个。因此,最简单的替代方法是检查用户是否已被告知使用 cookie 并首先显示 cookie 同意页面,否则在显示实际站点之前。

nginx再强大,当然也有办法解决上面的问题。实际上,我添加问题的原因是发布此答案,因为我相信它可能对其他人有帮助,当然对我也有帮助,以防随着时间的流逝我忘记了我是如何实现的,并且 google 以获得快速解决方案。废话不多说,下面是我在nginx配置文件中的解决方案:

location / {
  proxy_set_header HOST example.com;
  proxy_set_header X-Forwarded-For $remote_addr;
  
  if( $http_cookie ~* "consent" ) {
    proxy_pass https://example.com:8443;
  }
  
  # Setting `return 302` directly here doesn't work well
  # the first argument is just a filler as entering '@noconsent' only is disallowed
  try_files $uri/$arg_key @noconsent;
}

location @noconsent {
  return 302 "https://example.com/cookieconsent";
}

location /cookieconsent {
  root /path/to/www-root;
  expires max;
  try_files $uri/index.html $uri.html;
}

location /setconsent {
  add_header Set-Cookie 'consent=true;Domain=$host;Path=/;Max-Age=7776000;SameSite=strict;HTTPOnly;Secure';
  return 302 https://$host;
}

如果未设置 cookie,此配置的作用是 302 重定向到 'https://example.com/cookieconsent'。在那里,它搜索“/cookieconsent/index.html”和'cookieconsent.html'。这些文件中的任何一个都应该存在并且可以被服务器读取。它还应该包括一个按钮或 link 触发 '/setconsent'。然后,设置 consent cookie,使条件为 true 并触发 proxy_pass(在这种情况下加载 Nextcloud)。

这样做的好处是,在访问者按照 GDPR 法律的要求明确同意之前,可以完全在 HTML 中执行此操作而无需设置任何 cookie。另一方面,如果访问者不首先同意使用 cookie,则无法访问实际网站。