2010-09-10 7 views
21

J'utilise le micro-framework Flask basé sur Werkzeug, qui utilise Python.Flask/Werkzeug, comment retourner la page précédente après la connexion

Avant chaque page restreinte, il est un décorateur pour assurer que l'utilisateur est connecté, les retourner actuellement à la page de connexion si elles ne sont pas connectés, comme ceci:

# Decorator 
def logged_in(f): 
    @wraps(f) 
    def decorated_function(*args, **kwargs): 
     try: 
      if not session['logged_in']: 
       flash('Please log in first...', 'error') 
       return redirect(url_for('login')) 
      else: 
       return f(*args, **kwargs) 
     except KeyError: 
      flash('Please log in first...', 'error') 
      return redirect(url_for('login')) 
    return decorated_function 


# Login function 
@app.route('/', methods=['GET', 'POST']) 
def login(): 
    """Login page.""" 
    if request.method=='POST': 
    ### Checks database, etc. ### 
    return render_template('login.jinja2') 


# Example 'restricted' page 
@app.route('/download_file') 
@logged_in 
def download_file(): 
    """Function used to send files for download to user.""" 
    fileid = request.args.get('id', 0) 
    ### ... ### 

Une fois connecté, il a besoin pour renvoyer les utilisateurs à la page qui les a amenés à la page de connexion. Il doit également conserver des éléments tels que les variables transmises (c'est-à-dire l'intégralité du lien www.example.com/download_file?id=3)

Est-ce que quelqu'un sait comment faire cela?

Merci pour votre aide :-)

Répondre

20

Je pense que la pratique courante consiste à ajouter l'URL à laquelle l'utilisateur doit être redirigé après une connexion réussie à la fin de la chaîne de requête de l'URL de connexion.

Vous souhaitez changer votre décorateur à quelque chose comme ça (avec des licenciements dans votre fonction décorateur également supprimé):

def logged_in(f): 
    @wraps(f) 
    def decorated_function(*args, **kwargs): 
     if session.get('logged_in') is not None: 
      return f(*args, **kwargs) 
     else: 
      flash('Please log in first...', 'error') 
      next_url = get_current_url() # However you do this in Flask 
      login_url = '%s?next=%s' % (url_for('login'), next_url) 
      return redirect(login_url) 
    return decorated_function 

Vous aurez à remplacer quelque chose pour get_current_url(), parce que je ne sais pas comment cela est fait à Flask. Ensuite, dans votre gestionnaire de connexion, lorsque l'utilisateur se connecte, vous vérifiez s'il y a un paramètre next dans la requête et, si c'est le cas, vous le redirigez vers cette URL. Sinon, vous les redirigez vers une URL par défaut (généralement /, je suppose).

+1

+1 voir aussi le premier lien pour une petite fonctionnalité pratique de flask pour faire autre chose bloc – unmounted

+8

get_current_url() est flask.request.url –

11

Vous pouvez utiliser une chaîne de requête pour conserver les informations de fichier intactes sur un ou deux clics. L'une des bonnes choses à propos de url_for est comment il passes unknown parameters as query strings. Donc, sans changer votre page d'inscription trop, vous pourriez faire quelque chose comme ceci:

def login_required(f): 
    @wraps(f) 
    def decorated_function(*args, **kwargs): 
     if g.user is None: 
      return redirect(url_for('register', wantsurl = request.path)) 
     return f(*args, **kwargs) 
    return decorated_function 

Ici wantsurl gardera la trace de l'URL que l'utilisateur a atterri sur. Si un utilisateur non enregistré va à /download/some/file.txt, login_required vous enverra /register?wantsurl=%2Fdownload%2Fsome%2Ffile.txt Ensuite, vous ajoutez quelques lignes à votre fonction d'enregistrement:

@app.route('/register', methods=['GET', 'POST']) 
def register(): 
    if request.method == 'GET': 
     if 'wantsurl' in request.args: 
      qs = request.args['wantsurl'] 
      return render_template('register.html', wantsurl=qs) 
    if request.method == 'POST': 
     if 'wantsurl' in request.form and everything_else_ok: 
      return redirect(request.form['wantsurl']) 

Ce serait rediriger automatiquement vers le téléchargement sur l'enregistrement avec succès, à condition que vous avez quelque chose dans le formulaire appelé 'wanturl' avec la valeur qs, ou vous pourriez avoir votre formulaire soumis avec une chaîne de requête; cela pourrait juste être un peu si-autre dans le modèle.

Questions connexes