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 jsonfrom flask import Flask, request, make_response, render_templateapp = 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=mainset FLASK_ENV=developmentflask run -p 5000# 如果nginx应用docker时,须要应用localhost无法访问宿主机# 应用ip启动程序# nginx配置也须要应用ipflask run -h 本机ip -p 5000

docker nginx

内容地址
网站http://localhost:8881
根本配置/etc/nginx/nginx.conf
站点配置/etc/nginx/conf.d/default.conf

常用命令

nginx -s reloadvi /etc/nginx/conf.d/default.confrm -rf /etc/nginx/conf.d/default.confecho "" > /etc/nginx/conf.d/default.conf