Abstract
Specter Desktop is a desktop GUI for Bitcoin Core optimized to work with hardware wallets.
Specter already has a REST API system, but the authorization is currently done by HTTPBasicAuth
and to improve the security, HTTPTokenAuth
is really necessary. Access tokens would be a significant improvement.
My Project
I have to use access tokens for the token-based authorization, the access token I opted for was JSON Web Token (JWT) because:
I have already used it
I read their official documentation and got a fan of JWT and its advantages over Simple WebToken (SWT) and Security Assertion Markup Language Tokens (SAML). source
JWT authentication flow
Expected Outcomes:
User will be able to create a JWT token when the request is sent to a particular endpoint of the api
Once the token is generated the user can only see it once and the token needs to be stored somewhere in order to access sessions later on.
Authorization will be based on
HTTPTokenAuth
Project Progress
Headstart ๐
At first, when I went through Specterโs codebase it was difficult for me to understand and I was not able to figure out where to make the changes, but thanks to my mentor (k9ert) who helped me sort things out when I was stuck. He suggested making a small FLASK API in a similar structured way as Specterโs API was made. This really helped me understand Flask-RESTful
and Flask_HTTPAuth
.
PoC Implementation ๐
Step 1
The very first step was to install PyJWT
:
1 | pip install PyJWT |
Next, we need to create a โjwt_tokenโ variable in the UserMixin
of src/cryptoadvance/specter/user.py
, then we pass it in the user_dict
with the help of a property.
1 | class User(UserMixin): |
We also need to add helper functions in order to fetch and delete the token:
1 | def save_jwt_token(self, jwt_token): |
Step 2
This step includes the creation of token based endpoints in the API. For this I created a new file namely jwt.py
in the rest
directory.
Directory tree
1 | import jwt |
This basically includes the function generate_jwt
which takes user
as an argument and generates the token with the payload as user.username
and the expiry date of the token (exp
).
Then we have two endpoints - GET
and DELETE
which receive data from the User
model using user_manager
by passing the authenticated user
.
GET request functionality
DELETE request functionality
Last Step
The last step is to register the endpoints in the API, this can be done by adding:
1 | from .jwt import TokenResource |
in src/cryptoadvance/specter/api/rest/api.py
PR related to this project https://github.com/cryptoadvance/specter-desktop/pull/1785
Demo of the implemented PoC:
Future milestones
The plans for the rest of my journey are:
Adding a
verfiy_token
function that verifies if the given token is correct or not.Replacing
HTTPBasicAuth
withHTTPTokenAuth
Add one-time view functionality for the users.
Conclusion
Thank you for reading, hope you enjoyed it! Iโll continue to update my progress via the series of blogs ;)
Follow me on Twitter | LinkedIn for more web development-related tips and posts.
Thatโs all for today! You have read the article till the end.