[Django][Web]Djangoのsimple-jwtでログイン機能を実現(1)
その前に、私たちはすでにPyjwtを使用するログイン機能を実現しました!
しかし、このpyjwtは更新されず、pyjwtに比べてdjangoのsimple-jwtが実現しやすいため、現在進行中のプロジェクトはこのsimple-jwtで実現!😊
以前はトークン認証方法を学び,pyjwtを用いて実装したことがあるためsimple-jwtを用いて機能を実現することが容易である.
まずPOSTメソッドを使用してログインする場合、トークンを生成してクッキーに入れて送信するコードは以下の通りです.
最初はTokenObtainPairSerializerです.
これには、次のものが含まれます.
この応答トークンを使用してユーザーを識別し、accessトークンが期限切れになったときにrefreshトークンを使用してaccessトークンを再発行し、明日アップロードを継続します!☺️
しかし、このpyjwtは更新されず、pyjwtに比べてdjangoのsimple-jwtが実現しやすいため、現在進行中のプロジェクトはこのsimple-jwtで実現!😊
以前はトークン認証方法を学び,pyjwtを用いて実装したことがあるためsimple-jwtを用いて機能を実現することが容易である.
まずPOSTメソッドを使用してログインする場合、トークンを生成してクッキーに入れて送信するコードは以下の通りです.
# 로그인 : access, refresh 토큰 생성
def post(self, request):
email = request.data['email']
password = request.data['password']
user = User.objects.filter(email=email).first()
if user is None: # 해당 email의 user가 존재하지 않는 경우
return Response(
{"message": "존재하지않는 email입니다."}, status=status.HTTP_400_BAD_REQUEST
)
if not check_password(password, user.password): # 비밀번호에서 틀린 경우
return Response(
{"message": "비밀번호가 틀렸습니다."}, status=status.HTTP_400_BAD_REQUEST
)
if user is not None: # 모두 성공 시
token = TokenObtainPairSerializer.get_token(user)
refresh_token = str(token)
access_token = str(token.access_token)
response = Response(
{
"user": UserSeriallizer(user).data,
"message": "login success",
"jwt_token": {
"access_token": access_token,
"refresh_token": refresh_token,
},
},
status=status.HTTP_200_OK
)
response.set_cookie("access_token", access_token, httponly=True)
response.set_cookie("refresh_token", refresh_token, httponly=True)
return response
else: # 그 외
return Response(
{"message": "로그인에 실패하였습니다"}, status=status.HTTP_400_BAD_REQUEST
)
まず、紹介する組み込みシーケンス化器が2つあります.最初はTokenObtainPairSerializerです.
これには、次のものが含まれます.
class RefreshToken(BlacklistMixin, Token):
token_type = 'refresh'
lifetime = api_settings.REFRESH_TOKEN_LIFETIME
no_copy_claims = (
api_settings.TOKEN_TYPE_CLAIM,
'exp',
# Both of these claims are included even though they may be the same.
# It seems possible that a third party token might have a custom or
# namespaced JTI claim as well as a default "jti" claim. In that case,
# we wouldn't want to copy either one.
api_settings.JTI_CLAIM,
'jti',
)
@property
def access_token(self):
"""
Returns an access token created from this refresh token. Copies all
claims present in this refresh token to the new access token except
those claims listed in the `no_copy_claims` attribute.
"""
access = AccessToken()
# Use instantiation time of refresh token as relative timestamp for
# access token "exp" claim. This ensures that both a refresh and
# access token expire relative to the same time if they are created as
# a pair.
access.set_exp(from_time=self.current_time)
no_copy = self.no_copy_claims
for claim, value in self.payload.items():
if claim in no_copy:
continue
access[claim] = value
return access
class AccessToken(Token):
token_type = 'access'
lifetime = api_settings.ACCESS_TOKEN_LIFETIME
class TokenObtainSerializer(serializers.Serializer):
username_field = get_user_model().USERNAME_FIELD
default_error_messages = {
'no_active_account': _('No active account found with the given credentials')
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields[self.username_field] = serializers.CharField()
self.fields['password'] = PasswordField()
def validate(self, attrs):
authenticate_kwargs = {
self.username_field: attrs[self.username_field],
'password': attrs['password'],
}
try:
authenticate_kwargs['request'] = self.context['request']
except KeyError:
pass
self.user = authenticate(**authenticate_kwargs)
if not api_settings.USER_AUTHENTICATION_RULE(self.user):
raise exceptions.AuthenticationFailed(
self.error_messages['no_active_account'],
'no_active_account',
)
return {}
@classmethod
def get_token(cls, user):
raise NotImplementedError('Must implement `get_token` method for `TokenObtainSerializer` subclasses')
class TokenObtainPairSerializer(TokenObtainSerializer):
@classmethod
def get_token(cls, user):
return RefreshToken.for_user(user)
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
if api_settings.UPDATE_LAST_LOGIN:
update_last_login(None, self.user)
return data
以下を使用しました.token = TokenObtainPairSerializer.get_token(user) # refresh토큰 생성
refresh_token = str(token)
access_token = str(token.access_token) # access토큰 생성
そしてこの二つをビスケットに入れて、応答とともに伝えました!この応答トークンを使用してユーザーを識別し、accessトークンが期限切れになったときにrefreshトークンを使用してaccessトークンを再発行し、明日アップロードを継続します!☺️
Reference
この問題について([Django][Web]Djangoのsimple-jwtでログイン機能を実現(1)), 我々は、より多くの情報をここで見つけました https://velog.io/@ssssujini99/DjangoWeb-Django의-simple-jwt를-이용한-로그인-기능-구현1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol