# Django Rest Knox

***

**1. Create a Token API View**

```python
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_knox.models import AuthToken

class TokenObtainPairView(APIView):
    def post(self, request, format=None):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.save()
            token = AuthToken.objects.create(user)
            return Response({'token': token})
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
```

**2. Use the Knox Authentication Middleware**

```python
# settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_knox.authentication.KnoxAuthentication',
    ),
}
```

**3. Set the Token Model**

```python
# settings.py
REST_KNOX = {
    'TOKEN_MODEL': 'my_app.AuthToken'
}
```

**4. Customize the Token Expiration**

```python
# settings.py
REST_KNOX = {
    'TOKEN_TTL': timedelta(hours=12)  # Default: timedelta(hours=8)
}
```

**5. Disable the Token Limit**

```python
# settings.py
REST_KNOX = {
    'TOKEN_LIMIT_PER_USER': None  # Default: 10
}
```

**6. Use the Knox TokenSerializer**

```python
from rest_knox.serializers import TokenSerializer

class MyTokenSerializer(TokenSerializer):
    pass
```

**7. Use the Knox UserSerializer**

```python
from rest_knox.serializers import UserSerializer

class MyUserSerializer(UserSerializer):
    pass
```

**8. Create a Refresh Token API View**

```python
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_knox.models import AuthToken

class TokenRefreshView(APIView):
    def post(self, request, format=None):
        token = request.data.get('token')
        try:
            token = AuthToken.objects.get(token=token)
        except AuthToken.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        token.refresh()
        return Response({'token': token})
```

**9. Customize the Refresh Token Expiration**

```python
# settings.py
REST_KNOX = {
    'REFRESH_TOKEN_TTL': timedelta(days=1)  # Default: timedelta(hours=12)
}
```

**10. Use the Knox RefreshTokenSerializer**

```python
from rest_knox.serializers import RefreshTokenSerializer

class MyRefreshTokenSerializer(RefreshTokenSerializer):
    pass
```

**11. Create a Logout API View**

```python
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_knox.models import AuthToken

class LogoutView(APIView):
    def post(self, request, format=None):
        token = request.data.get('token')
        try:
            token = AuthToken.objects.get(token=token)
        except AuthToken.DoesNotExist:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        token.delete()
        return Response({"detail": "Successfully logged out."})
```

**12. Use the Knox LogoutSerializer**

```python
from rest_knox.serializers import LogoutSerializer

class MyLogoutSerializer(LogoutSerializer):
    pass
```

**13. Create a Knox Serializer Mixin**

```python
from rest_framework import serializers
from rest_knox.serializers import TokenSerializer

class KnoxSerializerMixin(serializers.ModelSerializer):
    token = TokenSerializer(read_only=True)
```

**14. Use the Knox Serializer Mixin in a ModelSerializer**

```python
from .models import MyModel
from .serializers import MyModelSerializer, KnoxSerializerMixin

class MyModelSerializer(KnoxSerializerMixin, serializers.ModelSerializer):
    class Meta:
        model = MyModel
```

**15. Create a Custom Knox Authentication**

```python
from rest_framework.authentication import BaseAuthentication
from rest_framework.request import Request
from rest_framework import exceptions
from rest_knox.models import AuthToken

class CustomKnoxAuthentication(BaseAuthentication):
    def authenticate(self, request: Request):
        token = request.headers.get('Authorization')
        if not token or 'Token' not in token:
            raise exceptions.AuthenticationFailed('No token provided.')

        token = token.split(' ')[1]
        try:
            token = AuthToken.objects.get(token=token)
        except AuthToken.DoesNotExist:
            raise exceptions.AuthenticationFailed('Invalid token.')

        return token.user, token
```

**16. Use the Custom Knox Authentication in a View**

```python
from rest_framework.views import APIView
from rest_framework.authentication import CustomKnoxAuthentication
from .serializers import MyModelSerializer

class MyView(APIView):
    authentication_classes = (CustomKnoxAuthentication,)

    def get(self, request):
        user = request.user
        serializer = MyModelSerializer(user)
        return Response(serializer.data)
```

**17. Create a Custom Knox Permission**

```python
from rest_framework.permissions import BasePermission
from rest_framework.request import Request

class CustomKnoxPermission(BasePermission):
    def has_permission(self, request: Request, view):
        if request.user.is_authenticated:
            return True
        return False
```

**18. Use the Custom Knox Permission in a View**

```python
from rest_framework.views import APIView
from rest_framework.permissions import CustomKnoxPermission
from .serializers import MyModelSerializer

class MyView(APIView):
    permission_classes = (CustomKnoxPermission,)

    def get(self, request):
        user = request.user
        serializer = MyModelSerializer(user)
        return Response(serializer.data)
```

**19. Create a Knox Token Manager**

```python
from rest_knox.models import AuthTokenManager

class MyAuthTokenManager(AuthTokenManager):
    pass
```

**20. Use the Knox Token Manager in the Token Model**

```python
from django.db import models
from rest_knox.models import AuthToken

class MyAuthToken(AuthToken):
    objects = MyAuthTokenManager()
```

**21. Create a Custom Knox API View**

```python
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_knox.models import AuthToken
from rest_framework.authtoken.serializers import AuthTokenSerializer

class CustomTokenObtainPairView(APIView):
    def post(self, request, format=None):
        serializer = AuthTokenSerializer(data=request.data)
        if serializer.is_valid():
            user = serializer.validated_data['user']
            token, _ = AuthToken.objects.create(user)
            return Response({'token': token})
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
```

**22. Use the Custom Knox API View in a URL Pattern**

```python
# urls.py
from django.urls import path
from .views import CustomTokenObtainPairView

urlpatterns = [
    path('api/token/', CustomTokenObtainPairView.as_view()),
]
```

**23. Create a Knox Token Field**

```python
from rest_framework import serializers
from rest_knox.models import AuthToken

class TokenField(serializers.ReadOnlyField):
    def get_attribute(self, instance):
        return AuthToken.objects.create(instance)[0]
```

**24. Use the Knox Token Field in a ModelSerializer**

```python
from .models import MyModel
from .serializers import TokenField

class MyModelSerializer(serializers.ModelSerializer):
    token = TokenField(source='*')
```

**25. Create a Knox Serializer Wrapper**

```python
from rest_framework.serializers import Serializer
from rest_knox.serializers import TokenSerializer

class KnoxSerializerWrapper(Serializer):
    token = TokenSerializer(read_only=True)
```

**26. Use the Knox Serializer Wrapper in a ViewSet**

```python
from rest_framework.viewsets import ModelViewSet
from .models import MyModel
from .serializers import KnoxSerializerWrapper

class MyViewSet(ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = KnoxSerializerWrapper
```

**27. Create a Knox Scoped Permission**

```python
from rest_framework.permissions import BasePermission
from rest_framework.request import Request

class KnoxScopedPermission(BasePermission):
    def has_permission(self, request: Request, view):
        if request.user.is_authenticated and request.user.has_perm('my_app.my_perm'):
            return True
        return False
```

**28. Use the Knox Scoped Permission in a View**

```python
from rest_framework.views import APIView
from rest_framework.permissions import KnoxScopedPermission
from .serializers import MyModelSerializer

class MyView(APIView):
    permission_classes = (KnoxScopedPermission,)

    def get(self, request):
        user = request.user
        serializer = MyModelSerializer(user)
        return Response(serializer.data)
```

**29. Create a Knox Token Generator**

```python
from rest_knox.auth import TokenGenerator

class MyTokenGenerator(TokenGenerator):
    pass
```

**30. Use the Knox Token Generator in the Token Model**

```python
from django.db import models
from rest_knox.models import AuthToken

class MyAuthToken(AuthToken):
    token_generator_class = MyTokenGenerator
```

**31. Create a Knox Token Expire Handler**

```python
from datetime import timedelta
from rest_knox.token import ExpireHandler

class MyExpireHandler(ExpireHandler):
    def token_expire_time(self, request, token):
        return timedelta(hours=24)  # Default: timedelta(hours=8)
```

**32. Use the Knox Token Expire Handler in the Token Model**

```python
from django.db import models
from rest_knox.models import AuthToken

class MyAuthToken(AuthToken):
    expire_handler_class = MyExpireHandler
```

**33. Create a Knox User Serializer Mixin**

```python
from rest_framework import serializers
from rest_knox.serializers import UserSerializer

class KnoxUserSerializerMixin(serializers.ModelSerializer):
    is_authenticated = serializers.SerializerMethodField()

    def get_is_authenticated(self, obj):
        return obj.is_authenticated
```

**34. Use the Knox User Serializer Mixin in a ModelSerializer**

```python
from .models import MyModel
from .serializers import KnoxUserSerializerMixin

class MyModelSerializer(KnoxUserSerializerMixin, serializers.ModelSerializer):
    class Meta:
        model = MyModel
```

**35. Create a Knox API Exception Handler**

```python
from rest_framework.exceptions import APIException

class KnoxAPIExceptionHandler(APIException):
    default_detail = 'Knox error.'
    default_code = 'knox'
```

**36. Use the Knox API Exception Handler in a View**

```python
from rest_framework.views import APIView
from rest_framework.response import Response
from .exceptions import KnoxAPIExceptionHandler

class MyView(APIView):
    def get(self, request):
        raise KnoxAPIExceptionHandler()
```
