jazzband / djangorestframework-simplejwt

A JSON Web Token authentication plugin for the Django REST Framework.
https://django-rest-framework-simplejwt.readthedocs.io/
MIT License
4.01k stars 662 forks source link

Getting a token takes nearly a second #820

Open AzureIP opened 3 months ago

AzureIP commented 3 months ago

Hi I am trying out this library with Django 5 and python 3.12. It works as expected, but getting a token for a user takes nearly a second. Around 950ms. Why? Is there some setting that improoves the generation time?

mohamed666666 commented 2 months ago

up

aperezlillo commented 5 days ago

This is probably caused by https://forum.djangoproject.com/t/stop-increasing-default-pbkdf2-iteration-count/25539, if you change the password hasher or reduce the steps this will reduce the performance (but you will require to recreate all hashes... and theoretically the application will be less secure)

ThirVondukr commented 3 days ago

@aperezlillo Affecting password security to gain performance is a bad idea. I recently stumbled upon pyjwt taking 25ms when creating a JWT, compared to around 1ms in rust/go. Fixing this could be a single line change in some cases - you have to manually load your key in case you're using RSA:

import time

import jwt
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa

key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
key_str = key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption(),
)

# key = serialization.load_pem_private_key(key_str.encode(), password=None)

t = time.perf_counter()
tok = jwt.encode(payload={}, key=key, algorithm="RS256")
print((time.perf_counter() - t) * 1000)

t = time.perf_counter()
tok = jwt.encode(payload={}, key=key_str, algorithm="RS256")
print((time.perf_counter() - t) * 1000)