|
|
## is52027c lab 15: logins
|
|
|
# is52027c lab 15: logins
|
|
|
|
|
|
For the next few weeks you should work on the **sql** version of the mytwit app.
|
|
|
|
|
|
Today we are going to add authenticated login to our mock twitter application ('mytwit'). To do this we will be using Flask sessions, which are cryptographically signed cookies (which means no one can change them).
|
|
|
|
... | ... | @@ -12,20 +13,25 @@ Ths steps we will follow are: |
|
|
|
|
|
Scripts for these steps will be added to the repo on Friday.
|
|
|
|
|
|
Note that to keep the main app cleaner, I am now putting specific parts of the code in separate files:
|
|
|
Note that to keep the main app cleaner, you should now put specific parts of the code in separate files:
|
|
|
|
|
|
* all the database code should go in a file called dbhelper.py, which is imported at the start of the app
|
|
|
|
|
|
from dbhelper import DBHelper
|
|
|
|
|
|
* the wtfforms definitions should go in a file called forms.py, and are also imported at the top of the app:
|
|
|
|
|
|
* all the database code is now in a file called dbhelper.py, which is imported at the start of the app
|
|
|
from dbhelper_8 import DBHelper
|
|
|
* the wtfforms definitions are in a file called forms.py, and are also imported at the top of the app:
|
|
|
from forms import addTwitForm, editTwitForm, loginForm
|
|
|
|
|
|
|
|
|
|
|
|
# task 1: simple login
|
|
|
|
|
|
_in the lab 15 repo this will be version \_7 of the script_
|
|
|
|
|
|
we will be using flask's sessions: you can read about them in the flask quickstart http://flask.pocoo.org/docs/0.12/quickstart/#sessions.
|
|
|
|
|
|
as before, our app needs a value for app.secret_key (so it can do the necessary encryptions)
|
|
|
as before, our app needs a value for app.secret\_key (so it can do the necessary encryptions)
|
|
|
|
|
|
note that you should use **flask-wtf** for your forms.
|
|
|
|
... | ... | @@ -35,14 +41,16 @@ constructing a simple login involves several steps: |
|
|
* create a flask view to handle that route
|
|
|
* create a database method that compares the username & password from the form with values from the database
|
|
|
* in the view, use a database method to check the username & password
|
|
|
* if they match, create a session (e.g. session['user_id'] = user_id), flash a 'success' message, and redirect to the index view
|
|
|
* if they match, create a session (e.g. session['user\_id'] = user\_id), flash a 'success' message, and redirect to the index view
|
|
|
* if not, flash an 'unsuccessful' message and re-display the form
|
|
|
* also create a /logout route and a view that logs the user out (e.g. session.pop('user_id', None) - see quickstart for more info)
|
|
|
* also create a /logout route and a view that logs the user out (e.g. session.pop('user\_id', None) - see quickstart for more info)
|
|
|
|
|
|
i also suggest that when the user is logged in their logged in status is displayed on every page. you can do this through the base template as the 'session' object is available in jinja by default (http://flask.pocoo.org/docs/0.12/templating/). to make this simple, as well as storing the user_id in the session, i also stored the username.
|
|
|
i also suggest that when the user is logged in their logged in status is displayed on every page. you can do this through the base template as the 'session' object is available in jinja by default (http://flask.pocoo.org/docs/0.12/templating/). to make this simple, as well as storing the user\_id in the session, i also stored the username.
|
|
|
|
|
|
# task 2: restrict access based on logged-in status
|
|
|
|
|
|
_in the lab 15 repo this will be version \_8 of the script_
|
|
|
|
|
|
now you can restrict access to key functions using the session.
|
|
|
|
|
|
make it so that only logged in users can add, edit or delete twits.
|
... | ... | @@ -56,6 +64,8 @@ an easy way to do this is to check if the session is set, and if not return an h |
|
|
|
|
|
# task 3: use flask-login
|
|
|
|
|
|
_in the lab 15 repo this will be version \_9 of the script_
|
|
|
|
|
|
now we will rewrite the login process to use the flask-login extension: you can find documentation for this extension here:
|
|
|
https://flask-login.readthedocs.io/en/latest/
|
|
|
|
... | ... | @@ -82,7 +92,7 @@ initiate that with the app after it has been created |
|
|
|
|
|
You will see from the flask-login documentation that you need to provide a user_loader callback. This callback is used to reload the user object from the user ID stored in the session. It should take the unicode ID of a user, and return the corresponding user object. You don't need to use this function directly but it needs to be there for flask-login to work.
|
|
|
|
|
|
In my version of the app, i create a db method that does this, so y callback function looks like:
|
|
|
In my version of the app, i create a db method that does this, so the callback function looks like:
|
|
|
|
|
|
@login_manager.user_loader
|
|
|
def load_user(user_id):
|
... | ... | @@ -90,7 +100,7 @@ In my version of the app, i create a db method that does this, so y callback fun |
|
|
if result:
|
|
|
return User(user_id)
|
|
|
|
|
|
As you will also see from the flask-login documentation, you also need to provide a user class that implements some specfic requirements. I have included user.py in the repo which will do this for you.
|
|
|
As you will also see from the flask-login documentation, you also need to provide a user class that implements some specific requirements. I have included user.py in the repo which will do this for you.
|
|
|
|
|
|
When using flask-login, instead of setting your own session on login, you use the user_id for the user to create a User instance, and pass that to the login_user method. In other words, like this
|
|
|
|
... | ... | @@ -110,6 +120,9 @@ Now that flask-login is working, access to any route / view can be restricted to |
|
|
|
|
|
## Task 4: hashing passwords
|
|
|
|
|
|
|
|
|
_in the lab 15 repo this will be version \_10 of the script_
|
|
|
|
|
|
Switching to hashed passwords doesn't require any changes in our main app, as we will still be passing the username and password from the form to the db functions for checking.
|
|
|
|
|
|
The changes are in how the password is stored and checked i.e. in the database class and in the database itself.
|
... | ... | |