Activity 46: Documentation of Python JWT
What is JWT and Its Importance?
JWT (JSON Web Token) is an open standard (RFC 7519) used for securely transmitting information between parties as a JSON object. It is commonly used for authentication and authorization in web applications. The main advantage of using JWT is that it enables the stateless authentication of users, meaning the server doesn't need to store any session information on the server-side. The information about the user is encoded and stored within the JWT itself.
Structure of JWT:
A JWT consists of three parts:
Header – Contains information about how the JWT is signed. It typically looks like:
{ "alg": "HS256", "typ": "JWT" }alg: The algorithm used for signing the token (e.g.,HS256).typ: The type of token (usuallyJWT).
Payload – Contains the claims. Claims are statements about an entity (typically, the user) and additional data. For example, it can hold the user’s ID, roles, or expiration time:
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }sub: Subject (usually the user ID).iat: Issued at timestamp.
Signature – A cryptographic signature created using the encoded header, payload, and a secret key. This ensures that the token has not been altered. It is created by:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)The signature allows the server to verify that the sender of the JWT is who it says it is and to ensure the message wasn’t tampered with.
Importance of JWT:
Stateless Authentication: Since the user information is encoded within the token, the server doesn't need to store session data. This improves scalability and performance.
Security: JWTs can be signed and optionally encrypted. The signed JWT ensures that the data cannot be tampered with.
Cross-Domain Authentication: JWTs can be used for Single Sign-On (SSO) applications across different domains.
Compact and URL-safe: JWTs are compact and can be transmitted as URL query parameters, inside HTTP headers, or within cookies.
Steps to Implement JWT Authentication in Flask
Let's walk through the steps to create a Flask application that uses JWT for user authentication. We will need the following routes:
POST /register– To register a new user.POST /login– To authenticate and get a JWT.GET /get-jwt– To get the JWT details (if valid).POST /set-jwt– To set a JWT (this can simulate storing a JWT in a session or cookie).
Step 1: Install Dependencies
First, you need to install the necessary libraries:
pip install Flask PyJWT
Flask: A web framework for building the app.PyJWT: A library to create and verify JWT tokens.

Step 2: Create the Flask App
Now, let's create the Flask app, configure JWT, and define the necessary routes.
from flask import Flask, request, jsonify, make_response
import jwt
import datetime
from werkzeug.security import generate_password_hash, check_password_hash
app = Flask(__name__)
# Secret key for JWT encoding and decoding
app.config['SECRET_KEY'] = 'your_secret_key'
# In-memory user storage for simplicity
users = {}
# Route 1: Register a new user (POST /register)
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
username = data.get('username')
password = data.get('password')
if username in users:
return jsonify({"message": "User already exists!"}), 400
hashed_password = generate_password_hash(password)
users[username] = hashed_password
return jsonify({"message": "User registered successfully!"}), 201
# Route 2: User login (POST /login) - Create JWT Token
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
username = data.get('username')
password = data.get('password')
# Check if user exists
if username not in users:
return jsonify({"message": "User not found!"}), 404
# Check password
if not check_password_hash(users[username], password):
return jsonify({"message": "Invalid password!"}), 401
# Create JWT token
token = jwt.encode({
'sub': username,
'iat': datetime.datetime.utcnow(),
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
}, app.config['SECRET_KEY'], algorithm='HS256')
return jsonify({"token": token})
# Route 3: Get JWT (GET /get-jwt)
@app.route('/get-jwt', methods=['GET'])
def get_jwt():
token = request.headers.get('Authorization') # e.g. 'Bearer <token>'
if not token:
return jsonify({"message": "Token is missing!"}), 400
try:
token = token.split()[1] # Get token from "Bearer <token>"
decoded_token = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
return jsonify({"message": "Token is valid", "payload": decoded_token})
except jwt.ExpiredSignatureError:
return jsonify({"message": "Token has expired!"}), 401
except jwt.InvalidTokenError:
return jsonify({"message": "Invalid token!"}), 401
# Route 4: Set JWT (POST /set-jwt)
@app.route('/set-jwt', methods=['POST'])
def set_jwt():
data = request.get_json()
token = data.get('token')
if not token:
return jsonify({"message": "Token is missing!"}), 400
try:
decoded_token = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
return jsonify({"message": "Token is valid", "payload": decoded_token})
except jwt.ExpiredSignatureError:
return jsonify({"message": "Token has expired!"}), 401
except jwt.InvalidTokenError:
return jsonify({"message": "Invalid token!"}), 401
if __name__ == '__main__':
app.run(debug=True)
Step 3: Code Explanation
/register:- Takes a
usernameandpasswordfrom the request body, hashes the password usingwerkzeug.security'sgenerate_password_hash, and stores the username and hashed password in an in-memory dictionary.
- Takes a
/login:- Takes
usernameandpasswordfrom the request body. It checks if the user exists, then checks if the password is correct. If valid, it creates a JWT token with a 1-hour expiration (exp) and returns it in the response.
- Takes
/get-jwt:- Accepts a GET request with the token in the
Authorizationheader (in the formatBearer <token>). It tries to decode the token using the secret key. If valid, it returns the token's payload. If the token is invalid or expired, it returns an error.
- Accepts a GET request with the token in the
/set-jwt:- This simulates receiving and validating a JWT token. It accepts the token in the POST request body, decodes it, and returns the decoded payload if the token is valid.
Step 4: Run the Flask Application
Save the above code to a file called app.py and run the following command:
python app.py
You can now interact with the API:
Register a user:
Send a POST request to
/registerwith JSON data:{ "username": "jov@outlook.com", "password": "ramonnnns" }
Login (Generate JWT):
Send a POST request to
/loginwith JSON data:{ "username": "jov@outlook.com", "password": "ramonnnns" }
Get JWT details:
Send a GET request to
/get-jwtwithAuthorization: Bearer <token>in the header.
Set JWT:
- Send a POST request to
/set-jwtwith a JSON body containing the JWT token.
- Send a POST request to
