美文网首页
解决Flask redirect生产环境上从https跳转到ht

解决Flask redirect生产环境上从https跳转到ht

作者: u14e | 来源:发表于2018-05-19 13:50 被阅读788次

背景


项目使用了nginx作为反向代理,从外部浏览器获取到https再反向代理到本地的http。错误配置文件如下

server {
    listen 443 ssl;
    # 启用ssl
    ssl on;
    
    server_name    bbs.u14e.xyz;

    # 证书和私钥的地址  
    ssl_certificate /var/www/u-bbs/u14exyz/full_chain.pem; 
    ssl_certificate_key /var/www/u-bbs/u14exyz/private.key;

    location /images {
        alias /var/www/u-bbs/app/images;
    }

    location /static {
        alias /var/www/u-bbs/app/static;
    }

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

flask redirect代码如下:用户登录成功后重定向到首页

@bp.route('/login', methods=['POST'])
@csrf_required
def login_post():
    form = request.form
    u = User.validate_login(form.to_dict())
    if u is not None:
        session['user_id'] = u.id
        session.permanent = True
        return redirect('/')
    else:
        flash('用户名或密码错误')
        return redirect(url_for('.login'))

部署上线后,使用https访问,登录后,地址被跳转到http://bbs.u14e.xyz,由于没有配80端口,所以这种情况会直接报错

原因


因为上面配置了几个proxy_set_header用来获取客户真实IP,使得flask redirect重定向的时候直接使用本机的协议,浏览器控制台查看响应头会看到Location: http://127.0.0.1:5000(还是不要删proxy_set_header这些配置)

尝试一


nginx添加80端口,使得redirect转到http后,nginx再将http转到https,443端口就可以将https转给本机的http了,如图:登录成功流程

image.png
server {
    listen 80;
    server_name bbs.u14e.xyz;
    location / {
        # redirect any requests to the same URL but on https
        return 301 https://$host$request_uri;
    }
}

PS:这样转来转去的显然很糟糕。当然最后还是要加上80端口的重定向的

尝试二:


使用url_for

return redirect(url_for('topic.index', _scheme="https", _external=True))

不过这样的话,之前的代码都要改一遍,而且开发环境不用https啊,还得手动切换,多麻烦啊!当然可以封装一下url_for,判断开发和生产环境,但是感觉还是太麻烦了。

尝试三:


参考:http://flask.pocoo.org/snippets/35/ 写个中间件,看了时间,年代久远,还是不试了。

终极方案


nginx配置文件添加,指定协议,参考:http://flask.pocoo.org/docs/1.0/deploying/wsgi-standalone/#proxy-setups

proxy_set_header X-Forwarded-Proto $scheme;

然后就可以了,可以了,可以了,是不是so easy~~~哈哈哈,只需要改一下nginx配置

最后附上nginx配置完整版


server {
    listen 80;
    server_name bbs.u14e.xyz;
    location / {
        # redirect any requests to the same URL but on https
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    # 启用ssl
    ssl on;
    
    server_name    bbs.u14e.xyz;

    # 证书和私钥的地址  
    ssl_certificate /var/www/u-bbs/u14exyz/full_chain.pem; 
    ssl_certificate_key /var/www/u-bbs/u14exyz/private.key;

    location /images {
        alias /var/www/u-bbs/app/images;
    }

    location /static {
        alias /var/www/u-bbs/app/static;
    }

    location / {
        proxy_pass http://127.0.0.1:5000;
        proxy_redirect off;
        proxy_set_header Host $host;
        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; # fix flask redirect生产环境 从https到http跳转
    }
}

参考链接:

相关文章

网友评论

      本文标题:解决Flask redirect生产环境上从https跳转到ht

      本文链接:https://www.haomeiwen.com/subject/lmiodftx.html