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

Breaking if no use auth model #150

Open shinneider opened 5 years ago

shinneider commented 5 years ago

I use django for micro services architecture, in this case i have a API Gateway to control the auth users

in each micro service i need user id only, to filter and return data, validation of jwt and user model is not necessary, but i can not remove django.contrib.auth and django.contrib.contenttypes, because raise a exption...

My settings.py:

INSTALLED_APPS = [
    # Django app's
    'django.contrib.staticfiles',

    # Third part app's
    'rest_framework',
    'corsheaders',
    'rest_framework_simplejwt',
    'django_mysql',

    # Developed app's
    ...
]

MIDDLEWARE = [
    # Django app's
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

    # Third part app's
    'corsheaders.middleware.CorsMiddleware',
]

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
            ],
        },
    },
]

AUTH_PASSWORD_VALIDATORS = []

REST_FRAMEWORK = {
    'UNAUTHENTICATED_USER': None,
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTTokenUserAuthentication',
    )
}

I have investigated and suggest these changes::

state.py

# change this
User = get_user_model()

# to
try:
    User = get_user_model()
except Exception:
    User = None

authentication.py

# add this in JWTTokenUserAuthentication
  def get_validated_token(self, raw_token):
        """
        Validates an encoded JSON web token and returns a validated token
        wrapper object.
        """
        messages = []
        for AuthToken in api_settings.AUTH_TOKEN_CLASSES:
            try:
                return AuthToken(raw_token, False)
            except TokenError as e:
                messages.append({'token_class': AuthToken.__name__,
                                 'token_type': AuthToken.token_type,
                                 'message': e.args[0]})

        raise InvalidToken({
            'detail': _('Given token not valid for any token type'),
            'messages': messages,
        })

model.py

class UserPermission:
    try:
        from django.contrib.auth import models as auth_models
        _groups = EmptyManager(auth_models.Group)
        _user_permissions = EmptyManager(auth_models.Permission)
    except:
        _groups = []
        _user_permissions = []

class TokenUser(UserPermission):

i'm testing it and i will give it my opinion this week if everything is ok. if all ok, i open a branch and submit a PR

to future i suggest an option to add groups and permissions in claims of jwt (also is great to front-ends permissions systems)

shinneider commented 5 years ago

I am still working on this issue. wait a little longer

struegamer commented 5 years ago

I am still working on this issue. wait a little longer

@shinneider did you find a solution for this issue?

shinneider commented 4 years ago

@struegamer I'm sorry for answering so late, a lot has happened since then.

But i don't find de solution, because after apply suggested changes, all tokens is not verified, and accepts expired tokens (What the hell), but in my organization we are using a simple API gateway that I developed, and user auth through the header

see a example in one of my repositories: https://github.com/shinneider/infoglobo-challenge

Note: is still under development and an unfinished version but may have a starting point

Andrew-Chen-Wang commented 4 years ago

@shinneider You can just use the JWT package instead of using this one. Take a look at authentication.py and backend.py for more info. I believe this repo is more for DRF + Authentication, so to not have a model for users is peculiar. Are you saying you have a database with all users for several services? Is it that you have one project with sharded dbs?