使用auth_request模塊實現nginx端鑒權控制
nginx-auth-request-module
該模塊是nginx一個安裝模塊,使用配置都比較簡單,只要作用是實現權限控制攔截作用。默認高版本nginx(比如1.12)已經默認安裝該模塊,下面介紹下使用該模塊實現多個站點之間的統一權限控制。
這里用一個例子來說明下,如下例子是包含site1(對應web1)、site2(對應web2)、auth(20.131:7001)在內的三個應用項目,auth項目主要做權限攔截,比如jwt校驗等,site1、site2分別為兩個受保護的資源站點,只有auth授權通過后才能訪問該站點。
實現上述要求nginx配置詳情如下(nginx地址為20.198):
upstream web1 {
server 192.168.20.131:3000;
}
upstream web2 {
server 192.168.20.131:3001;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /api/web1 {
auth_request /auth;
error_page 401 = @error401;
auth_request_set $user $upstream_http_x_forwarded_user;
proxy_set_header X-Forwarded-User $user;
proxy_pass http://web1;
}
location /api/web2 {
auth_request /auth;
error_page 401 = @error401;
auth_request_set $user $upstream_http_x_forwarded_user;
proxy_set_header X-Forwarded-User $user;
proxy_pass http://web2;
}
location /auth {
internal;
proxy_set_header Host $host;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_pass http://192.168.20.131:7001/auth;
}
location @error401 {
add_header Set-Cookie "NSREDIRECT=$scheme://$http_host$request_uri;Path=/";
return 302 http://192.168.20.131:7001/login;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
配置好之后,要明白一點,那就是nginx-auth-request-module模塊基本使用原理就是:
1、auth_request對應的路由返回401 or 403時,會攔截請求直接nginx返回前台401 or 403信息;
2、auth_request對應的路由返回2xx狀態碼時,不會攔截請求,而是構建一個subrequest請求再去請求真實受保護資源的接口;
所以,基於此,auth模塊只需要校驗然后返回相應的狀態碼即可實現權限攔截操作,簡單測試如下:
auth代碼:
// 授權認證接口
async auth() {
console.log(Date.now());
this.ctx.status = 200;
}
// 失敗后的登錄頁面
async login() {
console.log('失敗了........');
this.ctx.body = {
msg: '授權失敗',
code: 10001
}
}
這里的auth授權接口我們直接返回200,login是上述auth項目下配置的路由,用於授權失敗后302至登錄頁面用的。
site1和site2代碼相同,只羅列一個如下:
/* /api/web1/users,如果是web2則為/api/web2/users */
router.all('/', function(req, res, next) {
res.send('respond with a resource from web1');
});
這里只是簡單渲染輸出一個字符串而已,測試如下:
瀏覽器訪問:http://192.168.20.198/api/web1/users,輸出:
改變auth接口如下:
// 授權認證接口
async auth() {
console.log(Date.now());
this.ctx.status = 401;
}
// 失敗后的登錄頁面
async login() {
console.log('失敗了........');
this.ctx.body = {
msg: '授權失敗',
code: 10001
}
}
這里將狀態碼改為了401,再次訪問:http://192.168.20.198/api/web1/users,輸出:
這里可以看到,瀏覽器直接進行了302跳轉,因為鑒權失敗,直接重定向到登錄頁面了。
以上就是關於nginx-auth-request-module模塊的基本操作及配置,多個項目下部署統一的權限接口時還是相當有用的。