Skip to content

Multiple concurrency issues #638

@gbataille

Description

@gbataille

Hi all,

Issue

So for 2 years that I have been using django-oauth-toolkit, I have been plagued with concurrency issues of the form

DoesNotExist: AccessToken matching query does not exist

originally from

oauth2_provider/oauth2_validators.py in get_original_scopes at line 427

but after moving to version 1.1.2, it's

oauth2_provider/oauth2_validators.py in get_original_scopes at line 608

The thing is that (for me), 1.1.2 has also brought a new kind of issues

IntegrityError: duplicate key value violates unique constraint "oauth2_provider_accesstoken_source_refresh_token_id_key"
DETAIL:  Key (source_refresh_token_id)=(80187) already exists.

from

oauth2_provider/oauth2_validators.py in save_bearer_token at line 534
--> oauth2_provider/oauth2_validators.py in _create_access_token at line 566

I finally got to really look into them.

Problem

For me, those are concurrency issues that are due to the fact that we get the refresh_token from the db early in the process and that we try to use it later (to create a new access token for example).

I have drawn the process in a small diagram (source here)

With the problem being in between the 2 red steps.
We must not have 2 processes going to this rightmost branch with the same refresh token.

refresh_token_logic

To Reproduce

You can try and force some concurrency like so.
https://gist.github.com/gbataille/099a9eb4989c4277e9ce3312c8014391

Using it locally, I can make it fail in one of the 2 cases above quite often.

Fix

I think I have a fix. At least the logic seems sound, and I can't reproduce the issue anymore after applying it.

Submitting the PR

The key is to add the green step
refresh_token_logic_fixed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions