strawberry-django-auth 사용해보기

ron ron·2022년 11월 27일
0

1. 설치

pyproject.toml에 다음 코드 추가.

strawberry-django-auth = 
{
	git = "https://github.com/nrbnlulu/strawberry-django-auth.git",
    branch = "main"
}

poetry add strawberry-django-auth 쓰지 않고 위와 같이 하는 이유는 django 업데이트 버전에 대한 호환 추가가 github repository의 main branch에만 PR로 반영되어있기 때문이다.

이어서 프로젝트의 settings.py에 다음과 같이 추가한다.

# settings.py
from gqlauth.settings_type import GqlAuthSettings

INSTALLED_APPS = [
    # ...
    'django.contrib.staticfiles', # Required for GraphiQL
    "strawberry_django",
    "gqlauth",

]

MIDDLEWARE = [
    # ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # ...
]


AUTHENTICATION_BACKENDS = [
        "django.contrib.auth.backends.ModelBackend",
]

# to disable captcha validation just for ease of setup
GQL_AUTH = GqlAuthSettings(
    LOGIN_REQUIRE_CAPTCHA=False,
    REGISTER_REQUIRE_CAPTCHA=False,
)

TEMPLATES = [
    {
        # ...
        'APP_DIRS': True,
    },
]

2. Schema

schema.py에 다음을 추가한다.

# schema.py
import strawberry
from gqlauth.user.queries import UserQueries
from gqlauth.core.field_ import field
from gqlauth.core.types_ import GQLAuthError
from gqlauth.core.directives import TokenRequired

from typing import Union

from gqlauth.user import arg_mutations as mutations


@strawberry.type
class MyAuthorizedQueries(UserQueries):
    # add your queries that require authorization here.
    @strawberry.field
    def secured_string(self) -> str:
        return "secure"


@strawberry.type
class Query:
    @field(directives=[TokenRequired()])
    def auth_entry(self) -> Union[GQLAuthError, MyAuthorizedQueries]:
        return MyAuthorizedQueries()
        
        
@strawberry.type
class AuthMutation:
    # include here your mutations that interact with a user object from a token.

    verify_token = mutations.VerifyToken.field
    update_account = mutations.UpdateAccount.field
    archive_account = mutations.ArchiveAccount.field
    delete_account = mutations.DeleteAccount.field
    password_change = mutations.PasswordChange.field
    

@strawberry.type
class Mutation:
    @field(directives=[TokenRequired()])
    def auth_entry(self) -> Union[AuthMutation, GQLAuthError]:
        return AuthMutation()

    # these are mutation that does not require authentication.
    captcha = Captcha.field
    token_auth = mutations.ObtainJSONWebToken.field
    register = mutations.Register.field
    verify_account = mutations.VerifyAccount.field
    resend_activation_email = mutations.ResendActivationEmail.field
    send_password_reset_email = mutations.SendPasswordResetEmail.field
    password_reset = mutations.PasswordReset.field
    password_set = mutations.PasswordSet.field
    refresh_token = mutations.RefreshToken.field
    revoke_token = mutations.RevokeToken.field
    verify_secondary_email = mutations.VerifySecondaryEmail.field


schema = strawberry.Schema(query=Query, mutation=Mutation)

3. last_login 연동

tokenAuth(로그인) mutation을 호출해도 user model의 last_login 필드는 항상 null을 갖는다. 이유는, strawberry-django-auth 패키지의 tokenAuth(로그인) mutation이 django contrib 패키지의 auth model과 완벽히 연동되어 있지 않기 때문이다. 따라서 아래와 같이 strawberry-django-auth 패키지를 수정하자.

# /gqlauth/jwt/types_.py

from django.contrib.auth.signals import user_logged_in


class ObtainJSONWebTokenType(OutputInterface):
	
    # ...
    if status.verified or app_settings.ALLOW_LOGIN_NOT_VERIFIED:
        # successful login.
        user_logged_in.send(
        	sender=user.__class__, request=info.context.request, user=user
        )
        return ObtainJSONWebTokenType.from_user(user)
    # ...
# /gqlauth/user/resolvers.py

from django.contrib.auth.signals import user_logged_out


class RevokeTokenMixin(BaseMixin):

	# ...
    refresh_token = RefreshToken.objects.get(
    	token=input_.refresh_token, revoked__isnull=True
    )
    user = refresh_token.user
    user_logged_out.send(
    	sender=user.__class__, request=info.context.request, user=user
    )
    refresh_token.revoke()
    # ...

이제 아래와 같이 last_login이 값을 갖는다.

"user": {
  "username": "new_user",
  "email": "new_user@email.com",
  "lastLogin": "2022-11-27T07:09:52.421887+00:00"
}
profile
앱 개발자를 꿈꾸는.. 제조업 직원.. @_@

0개의 댓글