-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Added Flask-JWT-Extended #14
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
Conversation
… Use self.parser, instead of UserRegister.parser.
| "info": { | ||
| "_postman_id": "74a1833f-bc4e-4e85-a525-72d268ab9999", | ||
| "name": "Flask-JWT-Extended", | ||
| "description": "This collection contains requests associated witht the Flask-JWT-Extended section of the REST API course.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exported the Postman collection used to test the code for this section.
|
|
||
| - `POST: /login` | ||
| - Description: authenticate a user and ,if authenticated, respond with an access token and a refresh token. | ||
| - Description: authenticate a user and ,if authenticated, respond with a fresh access token and a refresh token. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the workflow slightly. We simply return a fresh access token when the user authenticates via credentials. We don't need a separate /fresh-login endpoint anymore.
sections_flask-jwt-extended/app.py
Outdated
| from flask_jwt_extended import JWTManager | ||
|
|
||
| from resources.refresh_token import TokenRefresh | ||
| from resources.user import UserRegister, UserLogin, UserFreshLogin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just put every resource related to user identity into resources.user
sections_flask-jwt-extended/app.py
Outdated
| api.add_resource(ItemList, '/items') | ||
| api.add_resource(UserRegister, '/register') | ||
| api.add_resource(UserLogin, '/login') | ||
| api.add_resource(UserFreshLogin, '/fresh_login') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's get rid of fresh login.
| 'name': self.name, | ||
| 'price': self.price, | ||
| 'store_id': self.store_id | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I choose to return more info in the json() method so it's more convenient when testing.
| @classmethod | ||
| def find_all(cls): | ||
| return cls.query.all() | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to keep resources unaware of what's happening internally, so let's put this code in the model method instead.
| items = [item.json() for item in ItemModel.find_all()] | ||
| if user_id: | ||
| return {'items': items}, 200 | ||
| return {'items': [item['name'] for item in items]}, 401 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use list comprehension instead of list() and map()
|
|
||
| if user and safe_str_cmp(user.password, data['password']): | ||
| access_token = create_access_token(identity=user.id) | ||
| access_token = create_access_token(identity=user.id, fresh=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always return fresh access token when the user authenticates via credentials.
| required=True, | ||
| help="This field cannot be blank." | ||
| ) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get rid of fresh login.
CristianoYL
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments
| """ | ||
| app.config['JWT_SECRET_KEY'] = 'jose' # we can also use app.secret like before, Flask-JWT-Extended can recognize both | ||
| app.config['JWT_BLACKLIST_ENABLED'] = True # enable blacklist feature | ||
| app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access', 'refresh'] # allow blacklisting for access and refresh tokens |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need refresh here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's true that we didn't blacklist any refresh token in the code. But I think we can keep it and talk about it, just to let the students know we can also blacklist a refresh token as well. In this way, we can freeze an account by all means.
sections_flask-jwt-extended/app.py
Outdated
| def add_claims_to_jwt(identity): | ||
| if identity == 1: # instead of hard-coding, we can read from a config file to get a list of admins instead | ||
| return {'isAdmin': True} | ||
| return {'isAdmin': False} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we stick to snake_case for consistency? is_admin instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, will update it now.
| def post(self): | ||
| current_user = get_jwt_identity() | ||
| new_token = create_access_token(identity=current_user, fresh=False) | ||
| return {'access_token': new_token}, 200 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we still doing token refreshes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I removed fresh login, but we still have refresh token. I'll add some more notes to explain these terms.
|
Some small improvements to the code. I also added some more detailed explanation in It should be finalized now. Let me know if there's anything wrong or any questions. |
|
I renamed the folder for |
Added Flask-JWT-Extended to replace Flask-JWT.
Introduced token refreshing, blacklisting, access control and other features.