【问题标题】:Very simple authentication using one-time cookie on nginx在 nginx 上使用一次性 cookie 进行非常简单的身份验证
【发布时间】:2012-05-29 22:32:52
【问题描述】:

我有一个仅供 3 位程序员私人使用的网站。它是由 nginx 直接提供的简单 HTML,但旨在供办公室内外使用。

我想要一个简单的密码或身份验证方案。我可以使用 HTTP 身份验证,但这些往往会经常过期,这让人们使用起来很痛苦。我也很紧张,有人闻比饼干更容易闻。

所以我想知道我是否可以在他们的浏览器上设置一个带有唯一长 ID 的 JavaScript cookie,并以某种方式告诉 nginx 只接受具有此 cookie 的请求(针对特定子域)。

这足够简单吗?我该怎么做

  1. 告诉 nginx 按 cookie 过滤
  2. 在浏览器中,设置一个永不过期的cookie?

【问题讨论】:

    标签: authentication cookies nginx password-protection http-authentication


    【解决方案1】:

    我从a blog post by Christian Stocker 找到了一个看起来非常简单的解决方案。它实现了以下规则:

    1. 如果用户在内部 IP 上,则允许他们使用。
    2. 如果用户设置了 cookie,则允许使用。
    3. 如果两者都不匹配,则会向用户显示 http 基本身份验证,并且如果他们成功验证身份,则会设置长期 cookie

    这真是两全其美。

    这是配置:

    map $cookie_letmein $mysite_hascookie {
      "someRandomValue" "yes";
      default           "no";
    }
     
    geo $mysite_geo {
      192.168.0.0/24 "yes"; #some network which should have access
      10.10.10.0/24  "yes"; #some other network which should have access
      default        "no";
    }
     
     
    map $mysite_hascookie$mysite_geo $mysite_authentication{
      "yesyes" "off";  #both cookie and IP are correct  => OK
      "yesno"  "off"; #cookie is ok, but IP not  => OK
      "noyes"  "off";  #cookie is not ok, but IP is ok => OK
      default  "Your credentials please"; #everythingles => NOT OK
    }
     
    server {
      listen 80;
      server_name mysite.example.org;
      location / {
        auth_basic  $mysite_authentication;
        auth_basic_user_file  htpasswd/mysite;
        add_header Set-Cookie "letmein=someRandomValue;max-age=3153600000;path=/"; #set that special cookie, when everything is ok
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
      }
    }
    

    【讨论】:

    • 第 7 行和第 8 行应该使用分号而不是冒号
    • @aag 谢谢!我刚刚修好了。
    【解决方案2】:

    要让 Nginx 通过 cookie 过滤,如果 cookie存在,您可以执行一些操作,然后您对 3 个有权访问的人执行实际操作,例如:

    server {
        listen 443 ssl http2;  # Use HTTPS to protect the secret
        ...
        if ($http_cookie !~ 'secretvalue') {
            return 401; 
        }
        location / {
           # Auth'd behaviour goes here
        }
    }
    

    要设置一个永不过期的 cookie,请在服务器主机名上的页面上启动浏览器的 JavaScript 控制台,然后输入:

    document.cookie = 'cookie=secretvalue;max-age=3153600000;path=/;secure';
    

    从技术上讲,这不是永远的,但 100 年应该可以做到。如果您愿意,也可以使用expires= 表示RFC1123 格式的绝对日期,并且可以根据需要轻松调整path。这也会在 cookie 上设置 secure 标志,因此它只会通过 HTTPS 发送。

    还有一些浏览器插件可以让您创建任意 cookie,但所有现代浏览器都有一个 JavaScript 控制台。

    【讨论】:

    • 我想你的意思是!~
    • 很好,@doronaviguy。更新了答案!
    • 如果 cookie 以明文形式发送,这会将秘密值泄露到公共互联网,这似乎不太好。我认为使用 TLS 足以保护机密,对吧?您也面临跨站点攻击的风险,对吧?
    • @DanielKing 更新了示例以使用 HTTPS 和安全 cookie。一般来说,它是一个 cookie,因此标准 cookie 处理/保护适用于网络传输和跨域访问。如果您的页面有 XSS,那么您在使用 DOM 可访问的 cookie 时遇到了麻烦,但是通过一些额外的服务器端工作,您可以实现 HttpOnly cookies
    猜你喜欢
    • 1970-01-01
    • 2011-12-27
    • 2014-01-01
    • 2017-10-07
    • 2014-07-09
    • 2015-07-20
    • 1970-01-01
    • 2016-02-23
    • 2019-12-01
    相关资源
    最近更新 更多