jazzband / djangorestframework-simplejwt

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

BulkwriteError when using MongoDb #598

Open Sajeyks opened 2 years ago

Sajeyks commented 2 years ago

I am using MongoDB and SimpleJWT in DjangoREST to authenticate and authorize users. After the first user logs in, everything seems okay and their refresh token is added to the Outstanding token table. But when I try to log in as a second user, I get the below error:

Internal Server Error: /accounts/login/
Traceback (most recent call last):     
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 857, in parse
    return handler(self, statement)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 929, in _insert
    query.execute()
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 397, in execute
    res = self.db[self.left_table].insert_many(docs, ordered=False)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\pymongo\collection.py", line 770, in insert_many
    blk.execute(write_concern, session=session)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\pymongo\bulk.py", line 533, in execute
    return self.execute_command(generator, write_concern, session)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\pymongo\bulk.py", line 366, in execute_command
    _raise_bulk_write_error(full_result)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\pymongo\bulk.py", line 140, in _raise_bulk_write_error
    raise BulkWriteError(full_result)
pymongo.errors.BulkWriteError: batch op errors occurred, full error: {'writeErrors': [{'index': 0, 'code': 11000, 'keyPattern': {'jti_hex': 1}, 'keyValue': {'jti_hex': None}, 'errmsg': 'E11000 duplicate key error collection: fsm_database.token_blacklist_outstandingtoken index: token_blacklist_outstandingtoken_jti_hex_d9bdf6f7_uniq dup key: { jti_hex: null 
}', 'op': {'id': 19, 'user_id': 7, 'jti': '43bccc686fc648f5b60b22df3676b434', 'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY1OTY1NDUzNCwiaWF0IjoxNjU5NTY4MTM0LCJqdGkiOiI0M2JjY2M2ODZmYzY0OGY1YjYwYjIyZGYzNjc2YjQzNCIsInVzZXJfaWQiOjd9.aQmt5xAyncfpv_kDD2pF7iS98Hld98LhG6ng-rCW23M', 'created_at': datetime.datetime(2022, 
8, 3, 23, 8, 54, 125539), 'expires_at': datetime.datetime(2022, 8, 4, 23, 8, 54), '_id': ObjectId('62eb00064621b38109bbae16')}}], 'writeConcernErrors': [], 'nInserted': 0, 'nUpserted': 0, 'nMatched': 0, 'nModified': 0, 'nRemoved': 0, 'upserted': []}

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\cursor.py", line 51, in execute
    self.result = Query(
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 784, in __init__
    self._query = self.parse()
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 869, in parse
    raise exe from e
djongo.exceptions.SQLDecodeError:

        Keyword: None
        Sub SQL: None
        FAILED SQL: INSERT INTO "token_blacklist_outstandingtoken" ("user_id", "jti", "token", "created_at", "expires_at") VALUES (%(0)s, %(1)s, %(2)s, %(3)s, %(4)s)
        Params: [7, '43bccc686fc648f5b60b22df3676b434', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY1OTY1NDUzNCwiaWF0IjoxNjU5NTY4MTM0LCJqdGkiOiI0M2JjY2M2ODZmYzY0OGY1YjYwYjIyZGYzNjc2YjQzNCIsInVzZXJfaWQiOjd9.aQmt5xAyncfpv_kDD2pF7iS98Hld98LhG6ng-rCW23M', datetime.datetime(2022, 8, 3, 23, 8, 54, 125539), datetime.datetime(2022, 8, 4, 23, 8, 54)]
        Version: 1.3.6

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\cursor.py", line 59, in execute
    raise db_exe from e
djongo.database.DatabaseError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\views\generic\base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "Y:\Django\projects\FSM\accounts\views.py", line 95, in post
    return Response(serializer.data, status=status.HTTP_200_OK)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\serializers.py", line 555, in data
    ret = super().data
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\serializers.py", line 255, in data
    self._data = self.to_representation(self.validated_data)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\serializers.py", line 509, in to_representation
    attribute = field.get_attribute(instance)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\fields.py", line 457, in get_attribute
    return get_attribute(instance, self.source_attrs)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework\fields.py", line 102, in get_attribute
    instance = instance()
  File "Y:\Django\projects\FSM\accounts\models.py", line 51, in tokens
    refresh = RefreshToken.for_user(self)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\rest_framework_simplejwt\tokens.py", line 247, in for_user
    OutstandingToken.objects.create(
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\query.py", line 457, in create
    obj.save(force_insert=True, using=self.db)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\base.py", line 743, in save
    self.save_base(using=using, force_insert=force_insert,
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\base.py", line 780, in save_base
    updated = self._save_table(
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\base.py", line 885, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\base.py", line 923, in _do_insert
    return manager._insert(
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\query.py", line 1301, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\models\sql\compiler.py", line 1441, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 99, in execute
    return super().execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 67, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 76, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\cursor.py", line 59, in execute
    raise db_exe from e
django.db.utils.DatabaseError
[04/Aug/2022 02:08:54] "POST /accounts/login/ HTTP/1.1" 500 273483
[04/Aug/2022 02:40:11] "GET /admin/token_blacklist/outstandingtoken/ HTTP/1.1" 200 7727

MongoDB seems to have a problem inserting the token for the second user in the outstanding table. How can I fix this?

I really appreciate any help you can provide.

Sajeyks commented 2 years ago

@jezdez @matthiask @com4 @xrmx Is there a fix to this issue?

Andrew-Chen-Wang commented 2 years ago

We don't support MongoDB. We have a primary key field that is explicitly set as id = models.BigAutoField(primary_key=True, serialize=False), so maybe you could try swapping somehow