通过Ngin的auth_request以及EpressJS构建权限验证系统
本文的内容是我的开源代码(https://github.com/e10101/AdminLogin)的中文说明。
项目主要是实现了通过合理配置Nginx的auth_request模块来实现对敏感路径下的内容进行访问限制。
代码
可通过Github访问:https://github.com/e10101/AdminLogin,来获取代码。如果可以的话,可以**Star**一下。
开发初衷
这个项目是为了解决网站中部分管理资源(路径)需要进行权限限制,但又不想通过复杂系统去实现而进行编写的项目.
同时这个项目也没有采用Nginx的auth_basic模块来实现权限限制.二是通过auth_request来进行的权限限制.
结构框架
本项目是基于NodeJS/ExpressJS/PassportJS以及Github的。
为讲解方便,假设存在:
服务器A(server1.example.com),其路径/installs上存有敏感信息,其他路径可公开访问,端口3003。
服务器B(login.example.com),为认证服务器,其上部署了本项目代码,端口4001。
系统以CentOS7.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 contentlocation /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配置
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无权限的错误。
根据服务器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等);
- 创建应用简单无需审核(此项排除了微信,微博等)。
关键字:Nginx, express, Github, JavaScript
版权声明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!