nginx 减少自定义账号鉴权
应用 nginx 反向代理实现
当一个站点外部程序是个黑盒(无奈批改外面的申请逻辑),如何减少本人的账号零碎鉴权
实现逻辑
- 应用 nginx 的反向代理性能
-
自定义账号零碎减少两个接口,一个页面 (为防止门路抵触,减少了 ”/xuxiaocong”,依据本人需要批改)
- 账号接口:POST “/xuxiaocong/login”,接管用户名和明码,输出正确则生成 token
- 鉴权接口:GET “/xuxiaocong/auth”,读取 cookie 中的 token,验证其有效性,无效返回 200 状态码,有效返回 401 状态码
- 登录页面:GET “/xuxiaocong/login”,登录页面,填写用户名和明码,将 token 写入 cookie
成果
- 用户拜访站点
- 触发 /auth 鉴权,token 有效时,跳转自定义登录页面
- 登录胜利后刷新页面,进入源站点
- 当 token 生效时,会从新弹出登录页面
- 如果源站点也有本人的账号,则须要输出两个账号密码,双重认证
demo 目录构造
-
root # 根目录
-
static # 动态文件(flask 框架)
-
xuxiaocong
- axios.min.js
- axios.min.map
-
-
templates # 页面(flask 框架)
- login.html # 登录页面
- main.py
- requirements.txt
-
nginx 配置
- 代理时减少鉴权(验证 cookie)
- 无权限时跳转 ATP 的 login 页面
- 验证胜利后 cookie 记录 token,跳转回原页面
- 因为原页面可能会有门路抵触,将门路命名为 ”/xuxiaocong” 这样比拟拗口的门路
- 理论我的项目门路中可减少 guid 等形式升高反复可能
- 所有合乎设置的门路都须要鉴权(调用 /xuxiaocong/auth 接口),肯定留神接口的高性能
server {
listen 80;
listen [::]:80;
server_name localhost;
location / { # 这里做演示,所有申请都须要鉴权,理论我的项目留神过滤条件
proxy_pass http://www.damengsanqian.com/; # 代理须要鉴权的站点
proxy_set_header X-Original-URI $request_uri;
auth_request /xuxiaocong/auth; # 鉴权接口
error_page 401 /xuxiaocong/login; # 401 跳转登录页面
}
# 门路代理
location /xuxiaocong {
proxy_pass http://localhost:5000/xuxiaocong;
auth_request off; # 该门路禁用鉴权
}
# 动态文件门路代理 (flask 框架限度)
location /static/xuxiaocong {
proxy_pass http://localhost:5000/static/xuxiaocong;
auth_request off; # 该门路禁用鉴权
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {root /usr/share/nginx/html;}
}
代码 (Python)
结尾所说的两个接口一个页面,用其余语言实现
- /requirements.txt
flask
- /main.py
import json
from flask import Flask, request, make_response, render_template
app = Flask(__name__)
# 登录,GET 获取页面,POST 验证账号密码并返回 token
@app.route('/xuxiaocong/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
resp = make_response(render_template('login.html'), 200)
return resp
else:
# 获取 post 数据
data = json.loads(request.get_data())
username = data.get('username')
password = data.get('password')
if username == '1' and password == '1':
return '7cp4VkZ3Nju1AOjy', 200
else:
return '账号或明码谬误', 400
# 鉴权
@app.route('/xuxiaocong/auth')
def auth():
token = request.cookies.get('xuxiaocong_token')
# 模仿校验 token
# time.sleep(1)
if token == '7cp4VkZ3Nju1AOjy':
return '200', 200
else:
return '无 token 或 token 生效', 401
- /templates/login.html
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<script src="{{url_for('static',filename='xuxiaocong/axios.min.js') }}"></script>
</head>
<body>
<h1> 应用 LCP/ATP 账号登录 </h1>
<p> 这里是测试 </p>
<p> 账号:1</p>
<p> 明码:1</p>
账号:<input type="text" name="username" id="username" />
<br />
明码:<input type="password" name="password" id="password" />
<br />
<input type="button" onclick="token()" value="登录" />
<script>
function token() {const username = document.getElementById("username").value
const password = document.getElementById("password").value
axios.post('/xuxiaocong/login', { username, password})
.then(function (response) {
// 设置 cookie
setCookie('xuxiaocong_token', response.data)
location.reload()})
.catch(function (error) {alert(` 产生谬误:${error.response.data}`)
})
}
function setCookie(name, value) {
const Days = 30;
const exp = new Date();
exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();}
</script>
</body>
</html>
我的项目
pip --default-timeout=200 install -r requirements.txt
set FLASK_APP=main
set FLASK_ENV=development
flask run -p 5000
# 如果 nginx 应用 docker 时,须要应用 localhost 无法访问宿主机
# 应用 ip 启动程序
# nginx 配置也须要应用 ip
flask run -h 本机 ip -p 5000
docker nginx
内容 | 地址 |
---|---|
网站 | http://localhost:8881 |
根本配置 | /etc/nginx/nginx.conf |
站点配置 | /etc/nginx/conf.d/default.conf |
常用命令
nginx -s reload
vi /etc/nginx/conf.d/default.conf
rm -rf /etc/nginx/conf.d/default.conf
echo "" > /etc/nginx/conf.d/default.conf