Guest User

Untitled

a guest
Feb 9th, 2018
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.06 KB | None | 0 0
  1. # Flask-Login: Do we really need a Login page?
  2.  
  3. ### Let's think about it for a moment...
  4.  
  5. Login page is a de-facto standard for web applications, no question. But do we really need a **separate**
  6. login page? Because after logging in we navigate users to somewhere else anyway right?
  7. So what we need is merely a login **form** not a login **page**. A separate login page comes with
  8. the need of `next` parameter to keep track of. Without redirection - we don't need it anymore.
  9.  
  10. With today's power of template engine. We can turns any page to a login form without a separate/dedicate
  11. login page and without `next` parameter to taking care of. Let's see how we can do that.
  12.  
  13. First we move login logic to **LoginManager.unauthorized_handler** where we will handle our login process.
  14. We then ditch the usual redirect mechanism we're used to redirect users to login page. Instead we replace the target page content
  15. with our login form - right on that page.
  16.  
  17. ```python
  18.  
  19. @login_manager.unauthorized_handler
  20. def unauthorized():
  21. if request.method == 'POST':
  22. login_id = request.form.get('login_id')
  23. password = request.form.get('password')
  24. user = User.query.filter_by(login_id=login_id, password=password).first()
  25. if user:
  26. login_user(user)
  27. return redirect(request.referrer) # redirect to target page if authenticated
  28. return render_template('login.html') # otherwise replace page content with login form
  29.  
  30. ```
  31. From the code above, `@login_manager.unauthorized_handler` intercepts all unauthorized requests to any `@login_required` decorated endpoints.
  32. Instead of redirect to a separate login page, it replace target page's content with login form using `render_template('login.html')`.
  33. This keep users lands on target page but with the login form presented instead of actual page content. Thus no `next` parameter to worry
  34. as users already get there.
  35.  
  36. Once users submit their credentials and is authenticated, it redirects them back to the same page using `request.referrer`. This maintain
  37. any URL paramters (if there is) and also flush away previous POST request so users can refresh the page without being ask to re-submit form data.
  38.  
  39. Finally, to make any page a login page, all we need is to allow **POST** request to the endpoint and decorate it with `@login_required`.
  40.  
  41. ```python
  42.  
  43. @app.route('/account', methods=['GET','POST']) # allow POST to every @login_required endpoint
  44. @login_required
  45. def account():
  46. # do stuff
  47. # other stuff
  48. return render_template('account.html', **locals())
  49.  
  50. ```
  51. And don't forget to remove a line that says `login_manager.login_view = 'whatever.login'` as we no longer need it.
  52.  
  53. Pretty simple right? And any page can now be a login page:
  54.  
  55. ```html
  56.  
  57. {% if current_user.is_anonymous %}
  58. <a href=/account>Log in</a>
  59. {% else %}
  60. # ...
  61. {% endif %}
  62.  
  63. ```
  64.  
  65. As a bonus, authenticated users will never see a login page as long as they are logged in. Unlike typical, separate login page where authenticated users can get there by typing login endpoint directly in the address bar.
  66.  
  67. This should make for a better login experience.
Add Comment
Please, Sign In to add comment