88

Django Rest Frameworkガイドを読み、すべてのチュートリアルを完了しました。すべてが理にかなっていて、本来の方法で機能しているように見えました。説明したように、基本認証とセッション認証が機能しました。

djangoレストフレームワーク-APIガイド

ただし、ドキュメントのトークン認証の部分で苦労しています。少し不足しているか、チュートリアルほど深くは説明されていません。

django-rest-framework-トークン認証

ユーザー用のトークンを作成する必要があると書かれていますが、models.pyのどこに記載されていますか?

誰かがドキュメントのトークン認証の部分を初めての人のためにもう少しよく説明できますか?

4

7 に答える 7

94

@ian-clellandはすでに正しい答えを提供しています。彼の投稿で言及されていない小さな部分がいくつかあるので、完全な手順を文書化します(私はDjango1.8.5とDRF3.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)
    

    または、より明確にしたい場合は、myappプロジェクトの下にsignals.pyという名前のファイルを作成します。上記のコードをその中に入れてから、__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. curlAPIへのアクセスをテストするために、またははるかに単純な代替httpieを使用して、私は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"
    }
    

それでおしまい!

于 2015-10-27T03:13:54.090 に答える
75

いいえ、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ファイルのどこにでも置くと、Djangoスレッドの起動時に登録されます)

トークンを特定の時間にのみ作成する必要がある場合は、ビューコードで、適切な時間にトークンを作成して保存する必要があります。

# 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)

トークンが作成(および保存)されると、認証に使用できるようになります。

于 2013-02-12T17:30:55.267 に答える
19

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():
       ...

それ以外の場合、トークン認証はまったく実行されません

于 2016-01-24T00:12:29.090 に答える
15

これに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シェルにドロップダウンして、データベース内のすべてのユーザーのトークンを作成できます。

>>> 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)

お役に立てば幸いです。

于 2014-01-21T01:32:35.307 に答える
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にあります。

于 2016-03-02T05:53:51.877 に答える
7

ここでの優れた回答に加えて、トークン認証へのより良いアプローチであるJSONWebトークン認証について言及したいと思います。http://getblimp.github.io/django-rest-framework-jwt/によって提供される実装は非常に使いやすいです。

利点については、この回答で詳しく説明されています。

于 2016-09-10T04:38:29.170 に答える
1

JSON Web Token Authenticationは、TokenAuthenticationよりも優れた代替手段です。このプロジェクトは、Django( http://getblimp.github.io/django-rest-framework-jwt/ )を使用してJWT Authを実装していますが、現在、プロジェクトは維持されていません。

別の方法については、次の手順を実行できます: https ://github.com/davesque/django-rest-framework-simplejwt

于 2019-09-19T10:22:32.383 に答える