web-dev-qa-db-ja.com

ユーザーにパスワードの再入力を強制せずにDjango JSON Web Token認証を行う方法は?

私のDjangoアプリケーションは認証に Rest Framework JWT を使用します。これは非常にエレガントに機能します。

ただし、構築に苦労しているユースケースがあります。 「パスワードを忘れた」ワークフローの実用的なソリューションをすでにコーディングしました。認証されていないユーザーが、自分の電子メールアドレスに送信する秘密のリンクをクリックした場合にのみ、パスワードをリセットできるようにします。ただし、パスワードリセットワークフローが正常に完了した後、ユーザーがユーザー名と(新しい)パスワードを再入力せずに自動的にログインするように、このソリューションを変更したいと思います。ユーザーエクスペリエンスを可能な限り摩擦のないものにするために、これを実行したいと思います。

問題は、ユーザーにパスワードを再入力させずに(または明らかに非常に悪いDBにクリアテキストで保存せずに)これを機能させる方法がわからないことです。以下は、JWTトークンを取得する現在の方法です。 12行目で、ユーザーの明確なパスワードが必要であることがわかります。私はそれを持っていません。暗号化されたパスワードのみをmy_user.passwordに保存しています。

クリアパスワードの代わりにmy_user.passwordで暗号化されたパスワードを使用してJWTを取得するにはどうすればよいですか?使用できない場合、このワークフローはどのようになりますか? Rest Framework JWTを使用して達成されましたか?

from rest_framework_jwt.views  import ObtainJSONWebToken
from rest_framework status
from Django.contrib.auth.models import User

my_user = User.objects.get(pk=1)
ojwt = ObtainJSONWebToken()

if "_mutable" in dir(request.DATA):
    mutable = request.DATA._mutable
    request.DATA._mutable = True
request.DATA['username'] = my_user.username
request.DATA['password'] = "<my_user's clear password>"
if "_mutable" in dir(request.DATA):
    request.DATA._mutable = mutable


token_response = ojwt.post(request)
if status.is_success(token_response.status_code):
     # Tell the user login succeeded!!
else:
     # Tell the user login failed.
     # But hopefully, this shouldn't happen
15
Saqib Ali

Django REST Framework JWTを使用する場合、通常、ユーザーが自分でトークンを生成していることが期待されます。あなたが代わりにトークンを生成しているためです。ユーザーの場合、標準のビューを使用して機能させることはできません。

ビューの DRF JWTの実行方法 と同様に、トークンを自分で生成する必要があります。これは、ビューコードに次のようなものを使用することを意味します

from rest_framework_jwt.settings import api_settings
from datetime import datetime


jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

my_user = User.objects.get(pk=1) # replace with your existing logic

payload = jwt_payload_handler(my_user)

# Include original issued at time for a brand new token,
# to allow token refresh
if api_settings.JWT_ALLOW_REFRESH:
    payload['orig_iat'] = timegm(
        datetime.utcnow().utctimetuple()
    )

return {
    'token': jwt_encode_handler(payload)
}

これにより、ユーザーのパスワードを知らなくても、ビュー内でトークンを手動で生成できるようになります。

20
Kevin Brown