2010-09-14 16 views
2

Sur mon site Pylons, j'ai mon formulaire de connexion envoyant ses données à 'https://mysite.com'. Après une connexion réussie, une redirection a lieu pour les envoyer à leur page de profil.Pylônes - Les redirections passeront de HTTPS à HTTP sauf si je spécifie le protocole ... Y at-il un moyen de résoudre ce problème?

redirect(url(controller='profile')) 

Cela envoie à l'utilisateur de http://mysite.com/profile au lieu de https://mysite.com/profile. La seule façon que j'ai trouvé pour résoudre ce problème est de changer la redirection vers:

redirect(url(controller='profile', protocol='https')) 

Le problème que j'ai avec ceci est « si, pour une raison quelconque, mon cert va et je dois déposer SSL » Je ne veux pas avoir à parcourir tout mon code à la recherche de toutes les redirections. Je spécifie le protocole 'https'. Je veux que mon login envoie l'utilisateur à HTTPS et c'est tout ...

Y a-t-il une raison? la redirection passe à HTTP? Y a-t-il un moyen de l'arrêter? :/

Répondre

0

Je personnalise le mappeur pour que chaque appel à « url » forcerait le protocole approprié ...
intérieur routing.py:

class CustomMapper(Mapper): 

    def generate(self, *args, **kwargs): 
     kwargs["protocol"] = "https" 
     return Mapper.generate(self, *args, **kwargs) 

def make_map(config): 
    """Create, configure and return the routes Mapper""" 
    map = CustomMapper(directory=config['pylons.paths']['controllers'], 
         always_scan=config['debug']) 
4

Depuis que j'ai passé deux heures patauger dans la pylônes/routes/bécher/etc Je pensais que je partagerais ma solution.

D'abord un peu de contexte. J'utilise un équilibreur de charge élastique (ELB) sur AWS avec terminaison SSL. L'application est conçue pour fonctionner uniquement sur https; c'est un monde post-incendiaire après tout. Il est en couches comme ceci:

ELB -> nginx -> pasteWSGI -> pylons 

ELB est joyeux bonne en termes de simplicité, mais tout appel à pylons.controllers.util.redirect déclencherait une redirection 302 « http: // monsite/». L'ELB ne changerait pas cela sur le chemin du retour (aucune raison de) et ainsi mon navigateur serait renvoyé au port 80 et il n'y a aucune ELB écoutant sur ce port.

J'ai essayé de mettre à jour le mappeur comme suggéré ci-dessus.

  1. cela n'a pas fonctionné,
  2. Je voulais que mes réoriente être relatif. Le passage à https dans Pylônes signifie que le générateur d'URL va chercher l'hôte pour créer une nouvelle URL (https: // localhost/....)

Notez que Mapper.redirect_to fonctionne hors de la boîte et les utilisations redirections relatives, il n'y a donc pas besoin de gâcher avec ça. Le problème fondamental est que controllers.redirect utilise un chemin de code légèrement différent. En particulier, dans Routes, le controllers.util.redirect n'est pas une redirection (il y a un "if routes et routes.redirect" qui correspond à False).

Ma solution: remplacer tous les appels à rediriger par une nouvelle méthode de contrôleur (appelée aussi redirection) pour changer les redirections de redirections absolues à relatives.

Le code est le suivant:

lib/aides.py

def relative_redirect(to_url, start_response): 
    """Returns a redirect that is compatible with AWS ELB (no absolute http responses) 
    Using pylons.controllers.util.redirect triggers an exception that'll be turned into a 302 
    But with an absolute path so the response does not contains https but simple http 
    """ 
    start_response("302 Found", [("Content-Type", "text/plain; charset=utf-8"), ("Location", url(to_url))]) 
    return ["You are being redirected to {0}".format(url(to_url))] 

Avec ce bit appelé à partir de la classe de base de mes contrôleurs:

class BaseController(WSGIController): 
    ... 
    def redirect(self, to_url): 
     """Force a relative redirection, to work with AWS ELB""" 
     return relative_redirect(to_url, self.start_response)