Skip to content

871392231/angular-flask-login

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

#NOTE unfinished project

## I noticed lots of people forking this piece of code, but it is unfinished code. I think the design is not good, refer it on your own risk!

[] tags
0.1 -- base application without user login
0.2 -- add unit test for restful api
0.3 -- add database support, update test case
0.4 -- add flask login for user page

[] test
curl -i http://localhost:5000/api/users
curl -i http://localhost:5000/app/views/public/about.html

[]references

https://github.com/jmcunningham/AngularJS-Learning
http://arthur.gonigberg.com/2013/06/29/angularjs-role-based-auth/
http://www.youtube.com/user/vidjadavemo
http://www.frederiknakstad.com/authentication-in-single-page-applications-with-angular-js/

[]knowledge
http://www.youtube.com/watch?v=8ILQOFAgaXE 25:23
http://www.youtube.com/watch?v=Lsg84NtJbmI 21 minutes
http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/
http://flask.pocoo.org/snippets/3/



"""
flask_login_app
==============

An example of how to implement get_auth_token and token_loader of Flask-Login.
This example builds on the excellent docs of flask-login which clearly explains
how to setup basic session based Authentication. 

This example uses the python module itsdangerous to handle the encryption and
decryption of the remember me token. 

Flask Version: 0.9
Flask-Login Version: 0.1.3
itsdangerous Version: 0.17

Author: Christopher Ross
Site: http://blog.thecircuitnerd.com/flask-login-tokens/
Version: 0.1a
"""
from datetime import timedelta
import md5

from flask import Flask, request, redirect, render_template
from flask_login import (LoginManager, login_required, login_user, 
                         current_user, logout_user, UserMixin)
from itsdangerous import URLSafeTimedSerializer

app = Flask(__name__)
app.debug = True
app.secret_key = "a_random_secret_key_$%#!@"

#Login_serializer used to encryt and decrypt the cookie token for the remember
#me option of flask-login
login_serializer = URLSafeTimedSerializer(app.secret_key)

#Flask-Login Login Manager
login_manager = LoginManager()

class User(UserMixin):
    """
    User Class for flask-Login
    """
    def __init__(self, userid, password):
        self.id = userid
        self.password = password

    def get_auth_token(self):
        """
        Encode a secure token for cookie
        """
        data = [str(self.id), self.password]
        return login_serializer.dumps(data)

    @staticmethod
    def get(userid):
        """
        Static method to search the database and see if userid exists.  If it 
        does exist then return a User Object.  If not then return None as 
        required by Flask-Login. 
        """
        #For this example the USERS database is a list consisting of 
        #(user,hased_password) of users.
        for user in USERS:
            if user[0] == userid:
                return User(user[0], user[1])
        return None

def hash_pass(password):
    """
    Return the md5 hash of the password+salt
    """
    salted_password = password + app.secret_key
    return md5.new(salted_password).hexdigest()

@login_manager.user_loader
def load_user(userid):
    """
    Flask-Login user_loader callback.
    The user_loader function asks this function to get a User Object or return 
    None based on the userid.
    The userid was stored in the session environment by Flask-Login.  
    user_loader stores the returned User object in current_user during every 
    flask request. 
    """
    return User.get(userid)

@login_manager.token_loader
def load_token(token):
    """
    Flask-Login token_loader callback. 
    The token_loader function asks this function to take the token that was 
    stored on the users computer process it to check if its valid and then 
    return a User Object if its valid or None if its not valid.
    """

    #The Token itself was generated by User.get_auth_token.  So it is up to 
    #us to known the format of the token data itself.  

    #The Token was encrypted using itsdangerous.URLSafeTimedSerializer which 
    #allows us to have a max_age on the token itself.  When the cookie is stored
    #on the users computer it also has a exipry date, but could be changed by
    #the user, so this feature allows us to enforce the exipry date of the token
    #server side and not rely on the users cookie to exipre. 
    max_age = app.config["REMEMBER_COOKIE_DURATION"].total_seconds()

    #Decrypt the Security Token, data = [username, hashpass]
    data = login_serializer.loads(token, max_age=max_age)

    #Find the User
    user = User.get(data[0])

    #Check Password and return user or None
    if user and data[1] == user.password:
        return user
    return None

@app.route("/logout/")
def logout_page():
    """
    Web Page to Logout User, then Redirect them to Index Page.
    """
    logout_user()
    return redirect("/")

@app.route("/login/", methods=["GET", "POST"])
def login_page():
    """
    Web Page to Display Login Form and process form. 
    """
    if request.method == "POST":
        user = User.get(request.form['username'])

        #If we found a user based on username then compare that the submitted
        #password matches the password in the database.  The password is stored
        #is a slated hash format, so you must hash the password before comparing
        #it.
        if user and hash_pass(request.form['password']) == user.password:
            login_user(user, remember=True)
            return redirect(request.args.get("next") or "/")        

    return render_template("login.html")

@app.route("/")
def index_page():
    """
    Web Page to display The Main Index Page
    """
    user_id = (current_user.get_id() or "No User Logged In")
    return render_template("index.html", user_id=user_id)

@app.route("/restricted/")
@login_required
def restricted_page():
    """
    web page which is restricted and requires the user to be logged in. 
    """
    #this is just to display the username in the template not required as part
    #of any Flask-Login requirements. 
    user_id = (current_user.get_id() or "No User Logged In")
    return render_template("restricted.html", user_id=user_id)

if __name__ == "__main__":

    #Create a quick list of users (username, password).  The password is stored
    #as a md5 hash that has also been salted.  You should never store the users
    #password and only store the password after it has been hashed. 
    USERS = (("user1", hash_pass("pass1")),
          ("user2", hash_pass("pass2"))
          )

    #Change the duration of how long the Remember Cookie is valid on the users
    #computer.  This can not really be trusted as a user can edit it. 
    app.config["REMEMBER_COOKIE_DURATION"] = timedelta(days=14)

    #Tell the login manager where to redirect users to display the login page
    login_manager.login_view = "/login/"
    #Setup the login manager. 
    login_manager.setup_app(app)    

    #Run the flask Development Server
    app.run()

About

How to do security with angularjs and flask

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 45.1%
  • CSS 41.2%
  • HTML 9.9%
  • JavaScript 3.8%