本文的內容是個人開源代碼(https://github.com/e10101/AdminLogin)的中文說明。
項目主要是實現了經過合理配置Nginx
的auth_request
模塊來實現對敏感路徑下的內容進行訪問限制。javascript
可經過Github訪問:https://github.com/e10101/AdminLogin,來獲取代碼。若是能夠的話,能夠Star一下。java
這個項目是爲了解決網站中部分管理資源(路徑)須要進行權限限制,但又不想經過複雜系統去實現而進行編寫的項目.nginx
同時這個項目也沒有采用Nginx
的auth_basic
模塊來實現權限限制.二是經過auth_request
來進行的權限限制.git
本項目是基於NodeJS
/ExpressJS
/PassportJS
以及Github的。github
爲講解方便,假設存在:
服務器A(server1.example.com),其路徑/installs
上存有敏感信息,其餘路徑可公開訪問,端口3003。
服務器B(login.example.com),爲認證服務器,其上部署了本項目代碼,端口4001。瀏覽器
系統以CentOS
7.2爲例,認證使用的Github
用戶認證。服務器
服務器A(server1)的Nginx配置文件微信
server { listen 80; listen [::]:80; server_name server1.example.com; location = /auth { internal; proxy_pass http://login.example.com; proxy_pass_request_body off; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } error_page 401 = @error401; location @error401 { return 302 http://login.example.com; } location / { try_files $uri $uri/ @proxy; } # The path has secret content location /installs { auth_request /auth; try_files $uri $uri/ @proxy; } location @proxy { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Host $remote_addr; proxy_pass http://127.0.0.1:3003; } }
服務器B(login)的Nginx配置cookie
server { listen 80; listen [::]:80; server_name login.example.com; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Host $remote_addr; proxy_pass http://127.0.0.1:4001/; } }
用戶訪問服務器A的敏感資源(即路徑/installs
中的內容),Nginx
經過配置文件中的auth_request
字段去請求http://login.example.com/auth,因爲用戶並未在服務器B進行登陸,所以服務器B返回了401
無權限的錯誤。session
根據服務器A的配置,發現401
錯誤後,會向用戶返回302
狀態指向爲服務器B的主機地址(login.example.com)。
用戶瀏覽器跳轉到服務器B,並選擇第三方的用戶認證進行受權(此處以Github爲例),當用戶經過Github進行受權後,迴向服務器B返回用戶的我的信息。
服務器B從第三方反饋回的信息中,檢索出用戶的用戶名(username
),而後服務器B會將此用戶名與已有的管理員信息進行對比(此處經過配置文件實現),若是登陸用戶爲合法的管理員帳號,則服務器B受權其登陸進入。若是爲非法用戶,則不對其受權,所以非法用戶沒法得到有效登陸憑證。
若是用戶爲合法用戶:
那麼服務器B將會生成session,並經過Set-cookie
命令告知用戶瀏覽器。用戶經過此Cookie便可得到服務器B的承認受權。當用戶經過此Cookie訪問服務器B中的/auth
目錄時,會返回200
的狀態碼。
若是用戶爲非法用戶:
那麼服務器B將不會session,因爲用戶沒法得到承認的Cookie,那麼當用戶再次訪問/auth
的路徑時,服務器會返回401
錯誤。
假設用戶已經受權成功,那麼當用戶訪問服務器A中的敏感內容/installs
時,服務器A訪問服務器B的/auth
路徑,此時返回200
狀態碼,服務器A則容許用戶進行訪問。
以上,經過auth_request
模塊以及相關配置就實現了對敏感內容的訪問限制。並且經過第三方的機制,也無需本身手工實現登陸功能。同時,此方案能夠對同一域名下的不一樣子域名中的內容進行訪問限制。能夠重複利用一個登陸系統,服務於多個其餘系統。
設置Express
的session時,因爲本案例中使用了不一樣的子域名(server1.example.com及login.example.com),須要特別設置cookie
的domain
項,以下所示:
app.use(session({ secret: config.session.secret, cookie: { path: config.cookie.path, domain: config.cookie.domain, maxAge: config.cookie.maxAge } }));
其中的domain格式爲:.example.com
。
關於爲什麼使用Github的問題。
國內能夠訪問(此項排除了Facebook,Google,Twitter等);
建立應用簡單無需審覈(此項排除了微信,微博等)。