Skip to content

Commit

Permalink
Merge pull request #4
Browse files Browse the repository at this point in the history
feat(auth): Correct typo and add JWT authentication
  • Loading branch information
lihuacai168 authored Nov 15, 2023
2 parents 233326d + 923454b commit 01156a0
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 5 deletions.
52 changes: 51 additions & 1 deletion apidemo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
https://docs.djangoproject.com/en/3.1/ref/settings/
"""
import os
from datetime import timedelta
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
Expand Down Expand Up @@ -38,6 +39,7 @@
'django.contrib.messages',
'django.contrib.staticfiles',
'employee',
'ninja_jwt',
]

MIDDLEWARE = [
Expand Down Expand Up @@ -206,4 +208,52 @@
},

},
}
}


NINJA_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'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,

'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'ninja_jwt.authentication.default_user_authentication_rule',
# 'USER_AUTHENTICATION_RULE': 'core.auth.default_user_authentication_rule',

'AUTH_TOKEN_CLASSES': ('ninja_jwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'TOKEN_USER_CLASS': 'django.contrib.auth.models.User',

'JTI_CLAIM': 'jti',

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

# For Controller Schemas
# FOR OBTAIN PAIR
'TOKEN_OBTAIN_PAIR_INPUT_SCHEMA': "core.auth.MyTokenObtainPairInputSchema",
# 'TOKEN_OBTAIN_PAIR_REFRESH_INPUT_SCHEMA': "ninja_jwt.schema.TokenRefreshInputSchema",
# # FOR SLIDING TOKEN
# 'TOKEN_OBTAIN_SLIDING_INPUT_SCHEMA': "ninja_jwt.schema.TokenObtainSlidingInputSchema",
# 'TOKEN_OBTAIN_SLIDING_REFRESH_INPUT_SCHEMA':"ninja_jwt.schema.TokenRefreshSlidingInputSchema",
#
# 'TOKEN_BLACKLIST_INPUT_SCHEMA': "ninja_jwt.schema.TokenBlacklistInputSchema",
# 'TOKEN_VERIFY_INPUT_SCHEMA': "ninja_jwt.schema.TokenVerifyInputSchema",
}


AUTHENTICATION_BACKENDS = [
'core.auth.CustomAuthBackend',
]
4 changes: 3 additions & 1 deletion apidemo/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""

from ninja_jwt.routers.obtain import obtain_pair_router

from employee.views import router as employee_router

Expand All @@ -26,6 +26,8 @@
api_v1 = NinjaAPI(version='1.0.0')

api_v1.add_router('/employee/', employee_router)
api_v1.add_router('/token', tags=['Auth'], router=obtain_pair_router)


urlpatterns = [
path("admin/", admin.site.urls),
Expand Down
56 changes: 56 additions & 0 deletions core/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# !/usr/bin/python3
# -*- coding: utf-8 -*-
from typing import Dict, Type

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from ninja import Schema
from ninja_jwt.schema import TokenObtainInputSchemaBase
from ninja_jwt.tokens import RefreshToken

from core.schemas import StandResponse


class UserSchema(Schema):
first_name: str
email: str


class MyTokenObtainPairOutSchema(Schema):
refresh: str
access: str
user: UserSchema


class MyTokenObtainPairInputSchema(TokenObtainInputSchemaBase):
@classmethod
def get_response_schema(cls) -> Type[Schema]:
# TODO now only work get pair token success
# not work at get token fail and refresh
return StandResponse[MyTokenObtainPairOutSchema]

@classmethod
def get_token(cls, user) -> Dict:
values = {}
refresh = RefreshToken.for_user(user)
values["refresh"] = str(refresh)
values["access"] = str(refresh.access_token)
values.update(
user=UserSchema.from_orm(user)
)
return {'data': values}


class CustomAuthBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
User = get_user_model()

try:
user = User.objects.get(username=username)
except User.DoesNotExist:
return None

if user.check_password(password):
return user
else:
return None
2 changes: 1 addition & 1 deletion employee/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ class EmployeeOut(EmployeeIn):


class EmployeeFilters(PageFilter):
first_name__contains: str = Field(None, alias="fisrt_name")
first_name__contains: str = Field(None, alias="first_name")
last_name__contains: str = Field(None, alias="last_name")
department_id: Optional[conint(ge=0)]
5 changes: 3 additions & 2 deletions employee/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@
from typing import Optional, Union

from ninja import Query, Router, Schema
from ninja_jwt.authentication import JWTAuth
from pydantic.fields import Field
from pydantic.types import conint

from core.schemas import DictId, PageSchema, StandResponse
from employee.employee_service_impl import employee_service_impl
from employee.schemas import EmployeeFilters, EmployeeIn, EmployeeOut

router = Router(tags=["employees"])
router = Router(tags=["employees"], auth=JWTAuth())

logger = logging.getLogger(__name__)


class Filters(Schema):
first_name__contains: str = Field(None, alias="fisrt_name")
first_name__contains: str = Field(None, alias="first_name")
last_name__contains: str = Field(None, alias="last_name")
department_id: Optional[conint(ge=0)]

Expand Down

0 comments on commit 01156a0

Please sign in to comment.