[python] Django Rest 프레임 워크 토큰 인증

Django Rest Framework 가이드를 읽고 모든 튜토리얼을 완료했습니다. 모든 것이 합리적이고 제대로 작동하는 것 같았습니다. 설명대로 기본 및 세션 인증이 작동했습니다.
http://django-rest-framework.org/api-guide

그러나 문서의 토큰 인증 부분으로 어려움을 겪고 있습니다. 약간 부족하거나 자습서만큼 깊이 들어 가지 않습니다.
http://django-rest-framework.org/api-guide/authentication/#tokenauthentication

사용자를 위해 토큰을 만들어야한다고 말하지만 models.py에서 어디에 있는지 명시합니까?

내 질문은 :

누군가가 문서의 토큰 인증 부분을 첫 번째 타이머에 대해 좀 더 잘 설명 할 수 있습니까?



답변

아니요, models.py에는 없습니다. 모델 측면에서해야 할 일은 적절한 앱 ( rest_framework.authtoken)을 INSTALLED_APPS. 이는 사용자에게 외래 키가 지정된 토큰 모델을 제공합니다.

해야 할 일은 토큰 개체를 언제 어떻게 생성해야하는지 결정하는 것입니다. 앱에서 모든 사용자가 자동으로 토큰을 받습니까? 아니면 특정 승인 된 사용자 만? 아니면 그들이 특별히 요청할 때만?

모든 사용자가 항상 토큰을 가져야하는 경우 링크 한 페이지에 자동으로 생성하도록 신호를 설정하는 방법을 보여주는 코드 스 니펫이 있습니다.

@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

(넣어 장고 스레드가 시작되면 어디서든하는 models.py 파일에, 그것은 등록됩니다)

토큰을 특정 시간에만 만들어야하는 경우보기 코드에서 적절한 시간에 토큰을 만들고 저장해야합니다.

# View Pseudocode
from rest_framework.authtoken.models import Token

def token_request(request):
    if user_requested_token() and token_request_is_warranted():
        new_token = Token.objects.create(user=request.user)

토큰이 생성 (및 저장)되면 인증에 사용할 수 있습니다.


답변

@ ian-clelland는 이미 정답을 제공했습니다. 그의 게시물에서 언급되지 않은 작은 부분이 몇 개 있으므로 전체 절차를 문서화하려고합니다 (Django 1.8.5 및 DRF 3.2.4 사용).

  1. 수퍼 유저를 만들기 전에 다음 작업을 수행 하십시오. 그렇지 않으면 수퍼 유저가 자신의 토큰을 생성하지 못합니다.

  2. settings.py로 이동 하여 다음을 추가하십시오.

    INSTALLED_APPS = (
        'rest_framework',
        'rest_framework.authtoken',
        'myapp',
    )
    
    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        ),
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
        )
    }
    
  3. myappmodels.py 에 다음 코드를 추가하십시오 .

    from django.db.models.signals import post_save
    from django.dispatch import receiver
    from rest_framework.authtoken.models import Token
    from django.conf import settings
    
    # This code is triggered whenever a new user has been created and saved to the database
    @receiver(post_save, sender=settings.AUTH_USER_MODEL)
    def create_auth_token(sender, instance=None, created=False, **kwargs):
        if created:
            Token.objects.create(user=instance)
    

    좀 더 명시 할 경우 또는,라는 파일을 생성 signals.py 아래 의 MyApp 프로젝트를. 위의 코드를 그 안에 넣은 다음 __init__.py에 다음을 작성하십시오.import signals

  4. 콘솔 창을 열고 프로젝트 디렉토리로 이동 한 후 다음 명령을 입력합니다.

    python manage.py migrate
    python manage.py makemigrations
    

    데이터베이스를 살펴보면 authtoken_token 이라는 테이블 이 key (토큰 값), created (생성 된 날짜 시간), user_id (auth_user 테이블의 id 열을 참조하는 외래 키) 필드로 생성되어야합니다.

  5. 를 사용하여 수퍼 유저를 만듭니다 python manage.py createsuperuser. 이제 를 사용하여 DB 의 authtoken_token 테이블을 살펴보면 select * from authtoken_token;새 항목이 추가 된 것을 볼 수 있습니다.

  6. 사용 curl또는 훨씬 간단한 대안 httpie 당신의 API에 대한 테스트 액세스, 나는 httpie을 사용하고 있습니다 :

    http GET 127.0.0.1:8000/whatever 'Authorization: Token your_token_value'
    

    그게 다야. 이제부터 모든 API 액세스에 대해 HTTP 헤더에 다음 값을 포함해야합니다 ( 공백에주의 ).

    Authorization: Token your_token_value
    
  7. (선택 사항) DRF는 사용자 이름과 암호를 제공하는 경우 사용자 토큰을 반환하는 기능도 제공합니다. urls.py에 다음을 포함하기 만하면됩니다 .

    from rest_framework.authtoken import views
    
    urlpatterns = [
        ...
        url(r'^api-token-auth/', views.obtain_auth_token),
    ]
    

    httpie를 사용하여 확인 :

    http POST 127.0.0.1:8000/api-token-auth/ username='admin' password='whatever'
    

    반환 본문에 다음이 표시되어야합니다.

    {
        "token": "blah_blah_blah"
    }
    

그게 다야!


답변

Django 1.8.2 및 나머지 프레임 워크 3.3.2에서 위의 모든 사항을 따르는 것은 토큰 기반 인증을 활성화하기에 충분하지 않았습니다.

REST_FRAMEWORK 설정이 django 설정 파일에 지정되어 있지만 함수 기반 뷰에는 @api_view 데코레이터가 필요합니다.

from rest_framework.decorators import api_view

@api_view(['POST','GET'])
def my_view(request):
    if request.user.is_authenticated():
       ...

그렇지 않으면 토큰 인증이 전혀 수행되지 않습니다.


답변

여기에 2 센트를 더하기 위해 사용자 생성 (및 활성화)을 처리하는 사용자 지정 사용자 관리자가있는 경우 다음과 같이이 작업을 수행 할 수도 있습니다.

from rest_framework.authtoken.models import Token
# Other imports

class UserManager(BaseUserManager):

    def create_user(self, **kwargs):
        """
        This is your custom method for creating user instances.
        IMHO, if you're going to do this, you might as well use a signal.

        """
        # user = self.model(**kwargs) ...
        Token.objects.create(user=user)

    #You may also choose to handle this upon user activation. 
    #Again, a signal works as well here.

    def activate_user(**kwargs):
        # user = ...
        Token.objects.create(user=user)

이미 생성 된 사용자가있는 경우 터미널의 python 셸에 드롭 다운하여 db의 모든 사용자에 대한 토큰을 생성 할 수 있습니다.

>>> from django.contrib.auth.models import User
>>> from rest_framework.authtoken.models import Token
>>> for user in User.objects.all():
>>> ...    Token.objects.create(user=user)

도움이 되었기를 바랍니다.


답변

사용자 토큰을 얻는 더 깨끗한 방법이 있습니다.

간단히 manage.py 셸을 실행하십시오.

그리고

from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
u = User.objects.get(username='admin')
token = Token.objects.create(user=u)
print token.key

그런 다음 DB_Schema.authtoken_token 테이블에서 레코드를 찾을 수 있습니다.


답변

여기에서 훌륭한 답변 외에도 토큰 인증에 대한 더 나은 접근 방식 인 JSON 웹 토큰 인증을 언급하고 싶습니다. http://getblimp.github.io/django-rest-framework-jwt/에서 제공하는 구현은 사용하기 매우 쉽습니다.

이점은 이 답변에 자세히 설명되어 있습니다 .


답변

JSON 웹 토큰 인증은 토큰 인증보다 나은 대안입니다. 이 프로젝트는 Django ( http://getblimp.github.io/django-rest-framework-jwt/ )로 JWT Auth를 구현 했지만 현재 프로젝트는 유지 관리되지 않습니다.

대안은 https://github.com/davesque/django-rest-framework-simplejwt를 따를 수 있습니다.