在nginx上使用一次性cookie的非常简单的身份验证

时间:2012-05-23 11:21:50

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

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

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

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

这很简单吗?我如何

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

2 个答案:

答案 0 :(得分:9)

要通过Cookie过滤Nginx,您可以在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控制台。

答案 1 :(得分:6)

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

  1. 如果用户使用内部IP,则允许他们使用。
  2. 如果用户设置了cookie,则允许他们使用。
  3. 如果两者都不匹配,则会向用户显示http基本身份验证,如果设置了成功验证长期Cookie,则
  4. 这真是两全其美。

    这是配置:

    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;
      }
    }