Django Rest 프레임 워크 토큰 인증


78

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

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

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

내 질문은 :

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

답변:


72

아니요, 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)

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


의 의미는 post_save 무엇입니까?
244boy

2
@ 244boy a 가 저장 될 때마다 (따라서 ) 호출 되도록 신호 핸들러create_auth_token 로 설정합니다 . 신호는 django의 내부 수명주기 이벤트 처리 메커니즘입니다. Userpost_savecreate_auth_token
Jim K.

86

@ 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"
    }
    

그게 다야!


자세한 의견 주셔서 감사합니다. 토큰은 어디에서 일치합니까? 무엇이든 편집 할 수 있습니까?
Vidya

1
@rrmo 토큰은 auth_token이라는 데이터베이스 테이블에 저장됩니다 (또는 비슷한 이름으로 정확한 이름을 기억할 수 없습니다. 테이블에는 사용자 모델에 대한 세 개의 열, 기본 키, 토큰 및 외래 키만 있습니다). 인증 요청이 수신 될 때마다 들어오는 토큰과 저장된 토큰을 비교하기 위해 데이터베이스 테이블을 가져 오는 것 같습니다.
Cheng

@Cheng Regarding Point # 3 : 코드를 신호 .py에 넣고 Django 1.9 import signals에서 __init__.py레이즈 django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet를 추가 합니다.
narendra-choudhary 2016 년

예를 들어 모바일 앱에서 토큰을 받으려면 어떻게해야하나요? 사용자 이름과 비밀번호를 사용하여 토큰을 생성하고 (예 : base64 토큰 생성) 요청에 전송합니까?
예수 Almaral - Hackaprende

@JesusAlmaral 토큰은 클라이언트 측이 아닌 서버 측에서 생성됩니다. 사용자가 등록 정보를 입력하고 서버로 전송하여 계정을 생성하면 계정과 함께 토큰이 생성됩니다. 토큰이 생성되면 해당 값을 클라이언트 측에 보낼 수 있습니다.
Cheng

18

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
몇 개의 찬성에도 불구하고이 답변은 매우 유용한 포인트를 추가합니다. @api_view 데코레이터가 없으면 뷰는 토큰 인증을 사용하지 않습니다. 선택한 답변에 추가 할 수 있습니다.
Paolo Stefan

2 년 반 후 ... 감사합니다
zobbo

14

여기에 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)

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


10

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

간단히 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 테이블에서 레코드를 찾을 수 있습니다.



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.