Flask/ Werkzeug, comment retourner la page précédente après la connexion
j'utilise le micro-framework Flask qui est basé sur Werkzeug, qui utilise Python.
avant chaque page restreinte il y a un décorateur pour s'assurer que l'utilisateur est connecté, les retournant actuellement à la page de connexion s'ils ne sont pas connectés, comme:
# 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)
### ... ###
après s'être connecté, il doit renvoyer les utilisateurs à la page qui les a amenés à la page de connexion. Il a également besoin de conserver des choses telles que les variables passées (c'est-à-dire le lien entier essentiellement www.example.com/download_file?id=3 )--2-->
est ce que quelqu'un sait comment faire cela?
Merci pour votre aide :-)
2 réponses
je pense que la pratique standard est d'ajouter L'URL à laquelle l'utilisateur doit être redirigé après une connexion réussie à la fin de l'interrogation de l'URL de connexion.
vous changeriez votre décorateur en quelque chose comme ceci (avec les redondances 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 devrez substituer quelque chose à get_current_url()
, parce que je ne sais pas comment on fait en fiole.
Puis, dans votre gestionnaire de connexion, lorsque l'utilisateur se connecte avec succès dans, vous de vérifier pour voir si il y a un next
paramètre dans la requête et, si c'est le cas, vous les redirigez vers cette URL. Sinon, vous les redirigez vers une URL par défaut (habituellement /
, je suppose).
vous pouvez utiliser une chaîne de requête pour garder les informations du fichier intactes sur un clic ou deux. Une des belles choses au sujet de url_for
est la façon dont il passe des paramètres inconnus comme chaînes de requête. Ainsi, 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
va suivre 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
puis 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'])
qui redirigerait automatiquement vers le téléchargement à l'enregistrement réussi, à condition que vous ayez quelque chose dans le formulaire appelé 'wantsurl' avec la valeur de qs
, ou vous pourriez avoir votre formulaire soumettre avec une chaîne de requête; cela pourrait juste être un peu si-else dans le modèle.