Skip to main content

A Django app that allows you to generate SIMPLE_JWT with two different lifetimes plus more options.

Project description

simplejwt_multisessions is a Django app based on djangorestframework-simplejwt that allows you to generate SIMPLE_JWT with two different lifetimes and session features.

Introduction

simplejwt_multisessions is an MIT licensed Django app that allows Django devs to generate refresh tokens with two different lifetimes i.e., “SHORT” and “LONG”. simplejwt_multisessions is designed to manage tokens and sessions together. This app also can assign different policies to each type of lifetime category.

Why use simplejwt_multisessions?

  • Generates “LONG” and “SHORT” simpleJWT lifetime.

  • Sets information of the session on the initialization. e.g., “Safari 15.6.1, iOS 15.6.1, iPhone”

  • Extendable option for each session type with different policies.
    1. Extension of the session after each request by generating a new refresh token.

    2. Extension of the session once after each specific timedelta by generating a new refresh token.

  • Limitable option for the available number of sessions. i.e., a User can log in as a “LONG” session

    with only 3 different Endpoints/Devices or the User can log in as a “SHORT” session at the same time with only 2 different Endpoints/Devices. 1. Sets max number of available sessions for each session type: “SHORT”, “LONG”. 2. Sets destroying oldest active sessions. i.e., if the user reaches the max number of active sessions then by logging a new session the oldest session will be destroyed.

  • Returns list of active i.e., not expired sessions assigned to requested user with its session_id.

  • Destroys sessions by their session_id.

  • Destroys all other active/not expired sessions except the one making the request.

  • Differentiable URLs for different APIs e.g., “login”, “refresh”, “list”, “destroy”, “destroyAllOther” and “logout”.

  • Most of API’s permission_classes are set to AllowAny and need to receive secret_key in the body of the request

    which is defined in settings of simplejwt_multisessions in settings.py and the rest are set to IsAuthenticated and need nothing else.

Requirements

User guide

Installation

  1. Install with pip:

$ python -m pip install simplejwt_multisessions
  1. Clone the repo into your Django Project

https://github.com/benyaamin/simplejwt_multisessions

settings.py configuration

To start using simplejwt_multisessions, after installation of requirements first you should add rest_framework_simplejwt.token_blacklist to INSTALLED_APPS in settings.py and then add simplejwt_multisessions to it.

# Django Project settings.py
INSTALLED_APPS = [
    # ...
    "rest_framework_simplejwt.token_blacklist",
    "simplejwt_multisessions",
    # ...
]

According to djangorestframework-simplejwt configuration instruction: https://django-rest-framework-simplejwt.readthedocs.io/en/latest/getting_started.html#project-configuration

# Django Project settings.py
REST_FRAMEWORK = {
    # ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # ...
        'rest_framework_simplejwt.authentication.JWTAuthentication'
    )
    # ...
}

You also need to add djangorestframework-simplejwt settings to settings.py https://django-rest-framework-simplejwt.readthedocs.io/en/latest/settings.html#settings

# Django project settings.py
from datetime import timedelta
#...

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=30),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': False,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,
    'JWK_URL': None,
    'LEEWAY': 0,

    'AUTH_HEADER_TYPES': ('Bearer',),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',

    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
    'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser',

    'JTI_CLAIM': 'jti',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

After adding SEIMPLE_JWT to your Django’s settings.py, Now you are good to add simplejwt_multisessions’s settings to settings.py

# Django project settings.py
JWT_MULTISESSIONS = {
    'SECRET': SECRET_KEY,
    'LONG_SESSION':{ # This section is the "LONG_SESSION" configuration.
        'REFRESH_TOKEN_LIFETIME': SIMPLE_JWT['REFRESH_TOKEN_LIFETIME'], # or you can set the timedelta what you wish e.g., timedelta(days = 29)

        'ROTATE_REFRESH_TOKENS': False, # If set this flag true then after each token refresh request a new refresh token will be generated and the old one will be blacklisted
        'UPDATE_LAST_LOGIN': False, # By settings this flag to true after each request the session `lastUpdateDate` updates.
        'BLACKLIST_AFTER_ROTATION': False,

        'EXTEND_SESSION': True, # This flag specifies whether should extend the refresh lifetime after each refresh request or shouldn't
        'EXTEND_SESSION_EVERY_TIME': False, # If `EXTEND_SESSION` is set to true this flag specifies to extend refresh lifetime with the exact amount of `REFRESH_TOKEN_LIFETIME`
        'EXTEND_SESSION_ONCE_AFTER_EACH': timedelta(days= 15), # If `EXTEND_SESSION` is set to true but `EXTEND_SESSION_EVERY_TIME` is set to False, then the refresh token will be extended as much as this property specifies.

        'LIMIT_NUMBER_OF_AVAIL_SESSIONS': True, # This feature decides to restrict the number of available sessions.
        'MAX_NUMBER_ACTIVE_SESSIONS': 5, # If `LIMIT_NUMBER_OF_AVAIL_SESSIONS` is set to true then this property defines the max number of active sessions and prevents requests to exceed more than its value.
        'DESTROY_OLDEST_ACTIVE_SESSION': True, # If `LIMIT_NUMBER_OF_AVAIL_SESSIONS` is set to true by setting this flag to true and the max number of requests exceeds `MAX_NUMBER_ACTIVE_SESSIONS` then the newly arrived request will destroy the oldest session and the new session will be initialized.
    },
    'SHORT_SESSION': { # This section is the "SHORT_SESSION" configuration. The features are as same as what is mentioned in the `LONG_SESSION` section.
        'REFRESH_TOKEN_LIFETIME': timedelta(days= 1),

        'ROTATE_REFRESH_TOKENS': False,
        'UPDATE_LAST_LOGIN': True,
        'BLACKLIST_AFTER_ROTATION': True,

        'EXTEND_SESSION': False,
        'EXTEND_SESSION_EVERY_TIME': False,
        'EXTEND_SESSION_ONCE_AFTER_EACH': timedelta(hours= 12),

        'LIMIT_NUMBER_OF_AVAIL_SESSIONS': True,
        'MAX_NUMBER_ACTIVE_SESSIONS': 2,
        'DESTROY_OLDEST_ACTIVE_SESSION': True,
    }
}

URLs

If you are intended to use simplejwt_multisessions you should instead of using URLs related to rest_framework_simplejwt use the URLs mentioned below:

# <root_of_your_django_project>/urls.py
#...
from simplejwt_multisessions.api.views import (
                                            initializeSession,
                                            refreshSession,
                                            listOfActiveSessions,
                                            destroySessionById,
                                            destroyAllOtherSessions,
                                            logout,
                                            )
#...
urlpatterns = [
    ...
    path('api/session/login/',              initializeSession,          name='initialize_session'),
    path('api/session/refresh/',            refreshSession,             name='refresh_session'),
    path('api/session/list/',               listOfActiveSessions,       name='list_sessions'),
    path('api/session/destroy/',            destroySessionById,         name='destroy_session_by_id'),
    path('api/session/destroyAllOther/',    destroyAllOtherSessions,    name="destroy_all_other"),
    path('api/session/logout/',             logout,                     name='logout'),
    #...
]

Usage

Login and Refresh

For logging in or initializing a new session you need five variables to mention in your request’s body:
  1. username: The username_field of the Django user model

  2. password: The password of the Django user model

  3. secret_key: The secret_key mentioned in JWT_MULTISESSIONS settings in settings.py

  4. session: The session type of the request options: [“LONG”, “SHORT”]

  5. info: This field can store arbitrary information about the session. for instance Device id or browser version or IP address e.g., “Safari 15.6.1, iOS 15.6.1, iPhone”. NOTICE: This field is not changeable after initialization.

curl \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"username": "benyamin", "password": "somepassword",
    "secret_key": "the_Secret_Key", "session": "LONG",
    "info": "sample info"}' \
    http://localhost:8000/api/session/login/

...
{
    "refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY2NTc1OTU2MywiaWF0IjoxNjYzMTY3NTYzLCJqdGkiOiJkOWFiYTMzYWNmMDg0ODU2YjJjMjA4OWJiYTFjZDc0YSIsInVzZXJfaWQiOjF9.zGwSDoJzoCEhIqwg3D4bRAwrnJ0DKRKSGOzdyyw__ho",
    "access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ",
    "session_id": "ozdyyw__ho-10"
}

Same as classic simpleJWT You can use the returned access token to prove authentication for a protected view:

curl \
-H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ" \
http://localhost:8000/api/some-protected-view/

When this access token expires, you can use the refresh token to obtain another access token: NOTICE: 1. Since refresh API’s permission_classes is AllowAny you need to enter the secret_key that is assigned in simplejwt_multisessions’s settings in settings.py. 2. You should enter “session” in your request’s body. This “session” must be the same as the one you used in the login request otherwise the session will be destroyed.

curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"refresh":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY2NTc1OTU2MywiaWF0IjoxNjYzMTY3NTYzLCJqdGkiOiJkOWFiYTMzYWNmMDg0ODU2YjJjMjA4OWJiYTFjZDc0YSIsInVzZXJfaWQiOjF9.zGwSDoJzoCEhIqwg3D4bRAwrnJ0DKRKSGOzdyyw__ho",
     "secret_key": "the_Secret_Key", "session": "LONG"}' \
http://localhost:8000/api/session/refresh/

...
{"access":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTcwNTA5LCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjQxNWMxNjcwMmVkNTRkYWM5MDk0OTkyMmExMjcyMTdjIiwidXNlcl9pZCI6MX0.gdSQUmoSt_-ir87xngbC7YIvwNsAXJaAy0l4IRfuT1I"}

List of all sessions

To see the list of user’s all active sessions you can use the list’s API. You have to enter “session” in the body of your request. “session” can be one of these options: [“SHORT”, “LONG”, “ALL”] 1. If you ask for “SHORT” sessions, in return you will just see the list of all short types of sessions and related info. 2. If you ask for “LONG” sessions, in return you will just see the list of all long types of sessions and related info. 3. If you ask for “ALL” sessions, in return you will see the list of all types of sessions and related info, and by “ALL”, it means “SHORT” and “LONG” sessions in total. NOTICE: Since this API’s permission_classes is set to IsAuthenticated the proof of authentication is mandatory.

  1. “session”: “SHORT”

curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ" \
-d '{"session":"SHORT"}' \
http://localhost:8000/api/session/list/
{
    "Short":
        {
            "Available Sessions":"0",
            "Sessions":[
                {
                    "session_id":"8e_ikeorsa-8",
                    "created_at":"2022-09-11T11:16:26Z",
                    "last_update":"2022-09-14T14:41:26Z",
                    "expires_at":"2022-09-15T14:41:26Z",
                    "session_info":"Safari 15.6.1, iOS 15.6.1, iPhone"
                },
                {
                    "session_id":"oetqjgyp1o-9",
                    "created_at":"2022-09-14T08:23:14Z",
                    "last_update":"2022-09-14T14:41:20Z",
                    "expires_at":"2022-09-15T14:41:20Z",
                    "session_info":"Chrome 105.0.0.0, OS X 10.15.7 64-bit"
                }
            ]
        }
}
  1. “session”: “LONG”

curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ" \
-d '{"session":"LONG"}' \
http://localhost:8000/api/session/list/
{
    "Long":
        {
            "Available Sessions":"2",
            "Sessions":[
                {
                    "session_id": "8oeptkbkk0-3",
                    "created_at": "2022-09-08T19:14:33Z",
                    "last_update": "2022-09-08T19:14:33.108983Z",
                    "expires_at": "2022-10-08T19:14:33Z",
                    "session_info": "iOS native app, V1.0.2"
                },
                {
                    "session_id": "sppfiktswq-4",
                    "created_at": "2022-09-08T19:14:59Z",
                    "last_update": "2022-09-08T19:14:59.905518Z",
                    "expires_at": "2022-10-08T19:14:59Z",
                    "session_info": "android native app, V1.4"
                },
                {
                    "session_id": "rvu6qdlcdc-5",
                    "created_at": "2022-09-08T19:15:22Z",
                    "last_update": "2022-09-08T19:15:22.407307Z",
                    "expires_at": "2022-10-08T19:15:22Z",
                    "session_info": "react native app, V2.5"
                },
            ]
        }
}
  1. “session”: “ALL”

curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ" \
-d '{"session":"ALL"}' \
http://localhost:8000/api/session/list/
{
    "Short":
        {
            "Available Sessions":"0",
            "Sessions":[
                {
                    "session_id":"8e_ikeorsa-8",
                    "created_at":"2022-09-11T11:16:26Z",
                    "last_update":"2022-09-14T14:41:26Z",
                    "expires_at":"2022-09-15T14:41:26Z",
                    "session_info":"Safari 15.6.1, iOS 15.6.1, iPhone"
                },
                {
                    "session_id":"oetqjgyp1o-9",
                    "created_at":"2022-09-14T08:23:14Z",
                    "last_update":"2022-09-14T14:41:20Z",
                    "expires_at":"2022-09-15T14:41:20Z",
                    "session_info":"Chrome 105.0.0.0, OS X 10.15.7 64-bit"
                }
            ]
        },
    "Long":
        {
            "Available Sessions":"2",
            "Sessions":[
                {
                    "session_id": "8oeptkbkk0-3",
                    "created_at": "2022-09-08T19:14:33Z",
                    "last_update": "2022-09-08T19:14:33.108983Z",
                    "expires_at": "2022-10-08T19:14:33Z",
                    "session_info": "iOS native app, V1.0.2"
                },
                {
                    "session_id": "sppfiktswq-4",
                    "created_at": "2022-09-08T19:14:59Z",
                    "last_update": "2022-09-08T19:14:59.905518Z",
                    "expires_at": "2022-10-08T19:14:59Z",
                    "session_info": "android native app, V1.4"
                },
                {
                    "session_id": "rvu6qdlcdc-5",
                    "created_at": "2022-09-08T19:15:22Z",
                    "last_update": "2022-09-08T19:15:22.407307Z",
                    "expires_at": "2022-10-08T19:15:22Z",
                    "session_info": "react native app, V2.5"
                },
            ]
        }
}

Destroy session by their id

Sometimes End-User wants to terminate one of its active sessions. This action can be done by knowing the “session_id” and using ‘destroy’’s API. NOTICE: Since this API’s permission_classes is set to IsAuthenticated the proof of authentication is mandatory.

curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ" \
-d '{"session_id":"rvu6qdlcdc-5"}' \
http://localhost:8000/api/session/destroy/
{}

Destroy all other sessions

This API allows the End-User to destroy all other active sessions except the one that makes the request. Necessary inputs: [“session”, “refresh”]. “session” specifies the session type to be destroyed. “refresh” specifies the considered “refresh” token assigned to the current request session and is excluded from being destroyed. NOTICE: Since this API’s permission_classes is set to IsAuthenticated the proof of authentication is mandatory.

  1. “session”: “SHORT”

curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ" \
-d '{"session":"SHORT",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY2NTc1OTU2MywiaWF0IjoxNjYzMTY3NTYzLCJqdGkiOiJkOWFiYTMzYWNmMDg0ODU2YjJjMjA4OWJiYTFjZDc0YSIsInVzZXJfaWQiOjF9.zGwSDoJzoCEhIqwg3D4bRAwrnJ0DKRKSGOzdyyw__ho"}' \
http://localhost:8000/api/session/destroyAllOther/
{}
  1. “session”: “LONG”

curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ" \
-d '{"session":"LONG",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY2NTc1OTU2MywiaWF0IjoxNjYzMTY3NTYzLCJqdGkiOiJkOWFiYTMzYWNmMDg0ODU2YjJjMjA4OWJiYTFjZDc0YSIsInVzZXJfaWQiOjF9.zGwSDoJzoCEhIqwg3D4bRAwrnJ0DKRKSGOzdyyw__ho"}' \
http://localhost:8000/api/session/destroyAllOther/
{}
  1. “session”: “ALL”

curl \
-X POST \
-H "Content-Type: application/json" \
-H "Authorization: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYzMTY4MTYzLCJpYXQiOjE2NjMxNjc1NjMsImp0aSI6IjBlZGZlMmY3MzhiMzRhOWFhYzQ4ZDhjYzAxOTVmZjEzIiwidXNlcl9pZCI6MX0.QCEqyFmXk5-yHZ4dYKnhNx80o9mgAYRdgFfUtgV1lQQ" \
-d '{"session":"ALL",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY2NTc1OTU2MywiaWF0IjoxNjYzMTY3NTYzLCJqdGkiOiJkOWFiYTMzYWNmMDg0ODU2YjJjMjA4OWJiYTFjZDc0YSIsInVzZXJfaWQiOjF9.zGwSDoJzoCEhIqwg3D4bRAwrnJ0DKRKSGOzdyyw__ho"}' \
http://localhost:8000/api/session/destroyAllOther/
{}

Logout

This API facilitates logging out the session. Necessary inputs: [“secret_key”, “refresh”]. The secret_key mentioned in JWT_MULTISESSIONS settings in settings.py. “refresh” must be the refresh token the one that makes the request and is about to log out.

curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"secret_key": "the_Secret_Key",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY2NTc1OTU2MywiaWF0IjoxNjYzMTY3NTYzLCJqdGkiOiJkOWFiYTMzYWNmMDg0ODU2YjJjMjA4OWJiYTFjZDc0YSIsInVzZXJfaWQiOjF9.zGwSDoJzoCEhIqwg3D4bRAwrnJ0DKRKSGOzdyyw__ho"}' \
http://localhost:8000/api/session/logout/
{}

License

The licenses of djangorestframework and djangorestframework-simplejwt projects have been included in this repository in the “licenses” directory.

MIT License

Copyright (c) 2022 Benyamin Agha Ebrahimi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simplejwt_multisessions-1.4.tar.gz (24.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simplejwt_multisessions-1.4-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

Details for the file simplejwt_multisessions-1.4.tar.gz.

File metadata

  • Download URL: simplejwt_multisessions-1.4.tar.gz
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.10.5

File hashes

Hashes for simplejwt_multisessions-1.4.tar.gz
Algorithm Hash digest
SHA256 8d3bf965205a924176dad91cd2d597bc9b2c5cd987a12a1cb0d88d6746026212
MD5 73e79aa0a1b06631b4317dc799661bb8
BLAKE2b-256 cb7eb2bcf3da66764fb50b9f3fb5efc04756b6815e8917d57145b14dc3fdf1b1

See more details on using hashes here.

File details

Details for the file simplejwt_multisessions-1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for simplejwt_multisessions-1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 e8cf2a997377d3cde963ece1f8d111c5fc69a3330cf583cf56242faec2979f81
MD5 a8db4c97c1800533d2956c2bb3a2f567
BLAKE2b-256 b6c8fccb2f0b01cae3ac8c239d7d34a9c57a882ad50856922d4d8dc353515ef2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page