Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added user logout using blacklist and revoking jit #16

Merged
merged 2 commits into from May 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 4 additions & 5 deletions section11/app.py
Expand Up @@ -3,7 +3,8 @@
from flask_jwt_extended import JWTManager

from db import db
from resources.user import UserRegister, UserLogin, User, TokenRefresh
from blacklist import BLACKLIST
from resources.user import UserRegister, UserLogin, User, TokenRefresh, UserLogout
from resources.item import Item, ItemList
from resources.store import Store, StoreList

Expand Down Expand Up @@ -35,13 +36,10 @@ def add_claims_to_jwt(identity):
return {'is_admin': False}


black_list = [4, 6] # user.id that are black listed (can be read from a file or db too)


# This method will check if a token is blacklisted, and will be called automatically when blacklist is enabled
@jwt.token_in_blacklist_loader
def check_if_token_in_blacklist(decrypted_token):
return decrypted_token['identity'] in black_list
return decrypted_token['jti'] in BLACKLIST


# The following callbacks are used for customizing jwt response/error messages.
Expand Down Expand Up @@ -101,6 +99,7 @@ def create_tables():
api.add_resource(UserLogin, '/login')
api.add_resource(User, '/user/<int:user_id>')
api.add_resource(TokenRefresh, '/refresh')
api.add_resource(UserLogout, '/logout')

if __name__ == '__main__':
db.init_app(app)
Expand Down
9 changes: 9 additions & 0 deletions section11/blacklist.py
@@ -0,0 +1,9 @@
"""
blacklist.py

This file just contains the blacklist of the JWT tokens–it will be imported by
app and the logout resource so that tokens can be added to the blacklist when the
user logs out.
"""

BLACKLIST = set()
58 changes: 31 additions & 27 deletions section11/resources/user.py
@@ -1,24 +1,32 @@
from flask_restful import Resource, reqparse
from werkzeug.security import safe_str_cmp
from flask_jwt_extended import create_access_token, create_refresh_token, jwt_refresh_token_required, get_jwt_identity
from flask_jwt_extended import (
create_access_token,
create_refresh_token,
jwt_refresh_token_required,
get_jwt_identity,
get_raw_jwt,
jwt_required
)
from models.user import UserModel
from blacklist import BLACKLIST

_user_parser = reqparse.RequestParser()
_user_parser.add_argument('username',
type=str,
required=True,
help="This field cannot be blank."
)
_user_parser.add_argument('password',
type=str,
required=True,
help="This field cannot be blank."
)

class UserRegister(Resource):
parser = reqparse.RequestParser()
parser.add_argument('username',
type=str,
required=True,
help="This field cannot be blank."
)
parser.add_argument('password',
type=str,
required=True,
help="This field cannot be blank."
)

class UserRegister(Resource):
def post(self):
data = self.parser.parse_args()
data = _user_parser.parse_args()

if UserModel.find_by_username(data['username']):
return {"message": "A user with that username already exists"}, 400
Expand All @@ -30,20 +38,8 @@ def post(self):


class UserLogin(Resource):
parser = reqparse.RequestParser()
parser.add_argument('username',
type=str,
required=True,
help="This field cannot be blank."
)
parser.add_argument('password',
type=str,
required=True,
help="This field cannot be blank."
)

def post(self):
data = self.parser.parse_args()
data = _user_parser.parse_args()

user = UserModel.find_by_username(data['username'])

Expand All @@ -58,6 +54,14 @@ def post(self):
return {"message": "Invalid Credentials!"}, 401


class UserLogout(Resource):
@jwt_required
def post(self):
jti = get_raw_jwt()['jti']
BLACKLIST.add(jti)
return {"message": "Successfully logged out"}, 200


class User(Resource):
"""
This resource can be useful when testing our Flask app. We may not want to expose it to public users, but for the
Expand Down