2010-09-10 19 views
21

Estoy utilizando el micro-framework Flask que se basa en Werkzeug, que usa Python.Flask/Werkzeug, cómo devolver la página anterior después de iniciar sesión

Antes de cada página restringida no es un decorador para asegurar que el usuario ha iniciado sesión, actualmente devolviéndolos a la página de inicio de sesión si no se registran en, así:

# 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) 
    ### ... ### 

Después de iniciar la sesión, que necesita para devolver a los usuarios a la página que los llevó a la página de inicio de sesión. También necesita retener cosas como las variables pasadas (es decir, todo el enlace básicamente www.example.com/download_file?id=3)

¿Alguien sabe cómo hacer esto?

Gracias por su ayuda :-)

Respuesta

20

Creo que la práctica habitual es añadir la URL a la que tiene que ser redirigido después de una conexión exitosa hasta el final de la cadena de consulta de la URL de inicio de sesión del usuario.

Se podría cambiar la decorador a algo como esto (con redundancias en su función decoradora también eliminado):

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 

que tendrá que sustituir algo para get_current_url(), porque no sé cómo eso es hecho en Flask.

Luego, en su controlador de inicio de sesión, cuando el usuario inicie sesión con éxito, verifique si hay un parámetro next en la solicitud y, de ser así, los redirecciona a esa URL. De lo contrario, los redirige a alguna URL predeterminada (generalmente /, supongo).

+1

+1 vea también el primer enlace para ver una pequeña característica útil del matraz para hacer ese otro bloque – unmounted

+8

get_current_url() es flask.request.url –

11

Puede utilizar una cadena de consulta para mantener intacta la información del archivo en un clic o dos. Una de las cosas buenas sobre url_for es cómo passes unknown parameters as query strings. Así, sin cambiar su página de registro demasiado usted podría hacer algo como esto:

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 

Aquí wantsurl hará un seguimiento de la URL al usuario aterrizó en. Si un usuario no registrado va a /download/some/file.txt, login_required le enviará a /register?wantsurl=%2Fdownload%2Fsome%2Ffile.txt A continuación, añadir un par de líneas a su función de registro:

@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']) 

Eso sería redirigir automáticamente a la descarga en el registro con éxito, siempre y cuando tenga algo en el formulario llamado 'wanturl' con el valor de qs, o puede enviar su formulario con una cadena de consulta; eso podría ser un poco if-else en la plantilla.

Cuestiones relacionadas