Flask url pour générer une URL http au lieu de https
J'utilise url_for
pour générer une url de redirection lorsqu'un utilisateur s'est déconnecté.
return redirect(url_for('.index', _external=True))
Cependant, lorsque j'ai changé la page en une connexionhttps , le url_for
me donne toujours http .
Je voudrais demander explicitement url_for
pour ajouter https au début de l'url.
Pouvez-vous me montrer comment le changer? Je regarde Flask docs, sans chance.
Merci.
5 réponses
Avec Flask 0.10, il y aura une bien meilleure solution disponible que wrapping url_for
. Si vous regardez https://github.com/mitsuhiko/flask/commit/b5069d07a24a3c3a54fb056aa6f4076a0e7088c7 , un paramètre _scheme
a été ajouté. Ce qui signifie que vous pouvez faire ce qui suit:
url_for('secure_thingy',
_external=True,
_scheme='https',
viewarg1=1, ...)
_scheme
définit le schéma D'URL, générant une URL comme https://..
au lieu de http://
. Cependant, par défaut, Flask ne génère que des chemins (sans hôte ni schéma), vous devrez donc inclure le _external=True
pour passer de /secure_thingy
à https://example.com/secure_thingy
.
Cependant, pensez à rendre votre site Web HTTPS uniquement à la place. Il semble que vous essayez d'appliquer partiellement HTTPS pour seulement quelques routes "sécurisées", mais vous ne pouvez pas vous assurer que votre URL https n'est pas modifiée si la page reliant à la page sécurisée n'est pas cryptée. Ceci est similaire à contenu mixte.
J'ai essayé la réponse acceptée avec un url_for
arg mais j'ai trouvé plus facile d'utiliser le PREFERRED_URL_SCHEME
config variable et définissez-la sur https avec:
app.config.update(dict(
PREFERRED_URL_SCHEME = 'https'
))
, Puisque vous n'avez pas à l'ajouter à tous les url_for
appeler.
Si vous voulez affecter le schéma D'URL pour toutes les URL générées par le serveur (url_for
et redirect
), plutôt que d'avoir à définir _scheme
à chaque appel, il semble que la réponse "correcte" soit d'utiliser le middleware WSGI, comme dans cet extrait: http://flask.pocoo.org/snippets/35/
(Ce bug Flask {[14] } semble confirmer que c'est le moyen préféré.)
Fondamentalement, si votre environnement WSGI a environ['wsgi.url_scheme'] = 'https'
, alors url_for
générera des URL https:
.
Je recevais des URLs http://
de url_for
parce que mon serveur a été déployé derrière un équilibreur de charge Elastic Beanstalk, qui communique avec le serveur en HTTP régulier. Ma solution (spécifique à Elastic Beanstalk) était comme ceci (simplifié à partir de l'extrait lié ci-dessus):
class ReverseProxied(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
scheme = environ.get('HTTP_X_FORWARDED_PROTO')
if scheme:
environ['wsgi.url_scheme'] = scheme
return self.app(environ, start_response)
app = Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app)
La partie spécifique au haricot élastique est HTTP_X_FORWARDED_PROTO
. D'autres environnements auraient d'autres moyens de déterminer si l'URL externe incluait https. Si vous voulez juste toujours utiliser HTTPS, vous pouvez définir inconditionnellement environ['wsgi.url_scheme'] = 'https'
.
PREFERRED_URL_SCHEME
n'est pas la façon de le faire. Il est ignoré chaque fois qu'une requête est en cours .
Définir _scheme
sur chaque appel url_for()
est extrêmement fastidieux, et PREFERRED_URL_SCHEME
ne semble pas fonctionner. Cependant, se débarrasser de ce que le schéma supposé de la requête est au niveau WSGI semble convaincre avec succès Flask de toujours construire des URL HTTPS:
def _force_https(app):
def wrapper(environ, start_response):
environ['wsgi.url_scheme'] = 'https'
return app(environ, start_response)
return wrapper
app = Flask(...)
app = _force_https(app)
Si vous accédez à votre site web via un proxy, Flask dectects correctement le schéma étant HTTP
.
Browser -----HTTPS----> Proxy -----HTTP----> Flask
La solution la plus simple consiste à configurer votre proxy pour définir l'en-tête X-Forwarded-Proto
. Flask détecte automatiquement cet en-tête et gère le schéma en conséquence. Il y a une explication plus détaillée dans la documentation Flask sous la section Configurations de Proxy . Par exemple, si vous utilisez Nginx, vous devrez ajouter la ligne suivante dans votre location
bloc.
proxy_set_header X-Forwarded-Proto $scheme;
Comme autre mentionné, si vous ne pouvez pas changer la configuration de votre proxy, vous pouvez utiliser le ProxyFix de werkzeug ou construire votre propre correctif comme décrit dans la documentation: http://flask.pocoo.org/docs/0.12/deploying/wsgi-standalone/#proxy-setups