Ultimate Guide to PyJWT for Secure API Token Management

Introduction to PyJWT

PyJWT is a Python library that allows developers to encode and decode JSON Web Tokens (JWT) easily and securely. This versatile library is indispensable for building authentication systems, secure APIs, and managing session tokens. In this guide, we will cover the essentials of PyJWT, delve into its APIs, and finish with a complete app example.

What is a JSON Web Token (JWT)?

JWT is an open standard (RFC 7519) that defines a compact way for securely transmitting information between parties as a JSON object. The information can be verified and trusted because it is digitally signed using a secret (HMAC algorithm) or a public/private key pair (RSA or ECDSA).

Installing PyJWT

To get started, install PyJWT via pip:

  pip install pyjwt

Encoding and Decoding JWTs

At the heart of PyJWT is its ability to encode and decode tokens. Here’s how you can use the library’s APIs:

Encoding a JWT

Use the jwt.encode() method to create a token:

  import jwt
  import datetime

  payload = {
      "user_id": 123,
      "role": "admin",
      "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)
  }
  secret = "your-256-bit-secret"
  token = jwt.encode(payload, secret, algorithm="HS256")
  print(token)

Decoding a JWT

To verify and decode a token, use the jwt.decode() method:

  decoded_data = jwt.decode(token, secret, algorithms=["HS256"])
  print(decoded_data)

This will return the original payload if the token is valid and hasn’t expired.

Handling Expired Tokens

PyJWT raises the jwt.ExpiredSignatureError exception if a token is expired. Always wrap decoding in a try-except block:

  try:
      decoded_data = jwt.decode(token, secret, algorithms=["HS256"])
  except jwt.ExpiredSignatureError:
      print("Token has expired")

Creating a Token with Additional Headers

Custom headers can be added during token creation:

  headers = {"kid": "key-id-example"}
  token_with_headers = jwt.encode(payload, secret, algorithm="HS256", headers=headers)
  print(token_with_headers)

Algorithms Supported by PyJWT

PyJWT supports multiple algorithms, including HS256, RS256, and ES256. For asymmetrical encryption like RSA, supply the private key during encoding:

  private_key = """-----BEGIN PRIVATE KEY-----
  YOUR-RSA-PRIVATE-KEY
  -----END PRIVATE KEY-----"""
  public_key = """-----BEGIN PUBLIC KEY-----
  YOUR-RSA-PUBLIC-KEY
  -----END PUBLIC KEY-----"""

  token = jwt.encode(payload, private_key, algorithm="RS256")
  decoded_data = jwt.decode(token, public_key, algorithms=["RS256"])
  print(decoded_data)

Complete Example: A Flask API Secured by PyJWT

Here’s a mini web application using Flask and PyJWT for authentication:

  from flask import Flask, request, jsonify
  import jwt
  import datetime

  app = Flask(__name__)
  secret = "your-256-bit-secret"

  @app.route("/login", methods=["POST"])
  def login():
      username = request.json.get("username")
      password = request.json.get("password")
      # Dummy check; replace with real user validation
      if username == "admin" and password == "password":
          payload = {
              "username": username,
              "exp": datetime.datetime.utcnow() + datetime.timedelta(hours=1)
          }
          token = jwt.encode(payload, secret, algorithm="HS256")
          return jsonify({"token": token})
      return jsonify({"message": "Invalid credentials"}), 401

  @app.route("/protected", methods=["GET"])
  def protected():
      token = request.headers.get("Authorization", "").split(" ")[-1]
      try:
          decoded = jwt.decode(token, secret, algorithms=["HS256"])
          return jsonify({"message": f"Hello, {decoded['username']}!"})
      except jwt.ExpiredSignatureError:
          return jsonify({"message": "Token expired"}), 401
      except jwt.InvalidTokenError:
          return jsonify({"message": "Invalid token"}), 401

  if __name__ == "__main__":
      app.run(debug=True)

In this example, users can log in to receive a token and use that token to access protected routes. The app demonstrates token creation, decoding, and error handling.

Conclusion

PyJWT is a lightweight and straightforward library that simplifies the process of handling JSON Web Tokens in Python applications. Whether you are building a web app, an API, or a distributed system, PyJWT is a great tool for managing secure tokens. Start using PyJWT today to secure your applications efficiently!

Leave a Reply

Your email address will not be published. Required fields are marked *