https://ichi.pro/ko/django-rest-framework-mich-nuxt-autheseo-google-sosyeol-logeu-in-eul-bildeuhago-jwt-tokeun-eul-saelo-gochineun-bangbeob--128806100117235

 

Django Rest Framework 및 Nuxt Auth에서 Google 소셜 로그인을 빌드하고 JWT 토큰을 새로 고치는 방법 1 부

Nuxt 및 Django에서 종단 간 소셜 로그인 화면 구축 개요 지난 몇 주 동안 저는 사이드 프로젝트를 진행해 왔습니다. 요구 사항 중 하나는 사용자가 Google 소셜 로그인을 사용하여 애플리케이션에 로

ichi.pro

Django와 Vue의 Social Login을 연동하는 방법이다. Wagtail은 Django 기반이기 때문에 사용방법이 동일하다. (다만 Wagtail에서는 views.py를 사용하지 않기 때문에 일부 수정이 필요하다.)

 

1. Nuxt App Build

튜토리얼대로 진행해보겠다. 

 

환경은 python 3.8로 진행했다. 필요 module은 진행하면서 설치할 계획이다.

 

1) 먼저 project 폴더를 생성해주자.

mkdir google-login
cd google-login

2) front라는 이름의 vue 프로젝트를 생성해주자. 

npm init nuxt-app frontend

3) 아래와 같이 설정을 진행하면 된다. 

? Project name: google-login
? Programming language: JavaScript
? Package manager: Npm
? UI framework: Buefy
? Nuxt.js modules: enter를 눌러주자
? Linting tools: enter를 눌러주자
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Static (Static/JAMStack hosting)
? Development tools: enter를 눌러주자
? What is your GitHub username? sdil
? Version control system: Git

Vue에 대해서 자세하게 다루는 글이 아니기 때문에 세부설정에 대한 설명은 하지 않겠다. 

 

4) nuxt auth와 axios를 설치해주자.

cd frontend
npm install --save-exact @nuxtjs/auth-next
npm install @nuxtjs/auth-next @nuxtjs/axios

5) nuxt.config.js 수정

frontend/nuxt.config.js

  modules: [
    // https://go.nuxtjs.dev/buefy
    'nuxt-buefy',
    '@nuxtjs/axios',
    '@nuxtjs/auth-next',
  ],
  auth: {
    strategies: {
      google: {
        clientId: 'to be added'
      }
    }
  },

위와 같이 설정을 바꿔주자. 

 

6) login.vue 작성

frontend/pages/login.vue

<template>
  <section class="section">
    <b-button @click="loginWithGoogle()" icon-left="google">
      Sign in with Google
    </b-button>
  </section>
</template>

<script>
export default {
  methods: {
    loginWithGoogle() {
      this.$auth.loginWith("google");
    },
  },
};
</script>

Social Login을 위한 Google로그인 버튼을 생성했다. 

 

7) protect.vue 작성

frontend/pages/protected.vue

<template>
  <section class="section">
      {{ $auth.user.email }}
  </section>
</template>

<script>
export default {
  middleware: 'auth'
};
</script>

Nuxt Auth 미들웨어를 활성화 했다. 사용자가 로그인했을 때만 Page에 Access 할 수가 있다. 로그인 하지 않으면 사용자가 로그인 페이지로 Redirection 된다. 

 

8) 작동 Test

nuxt dev

# 문제가 발생하는 경우에는 npm install nuxt -g

9) localhost:3000/login 이동

login 버튼을 생성해 놓은 login page로 이동해서 google login 버튼을 누르면 400 승인 오류가 발생할 것이다. 걱정할 필요 없다. 아직 Google OAuth 설정을 하지 않았기 때문이다. 

 

2. Wagtail API 서버 구축

1) wagtail 설치, 프로젝트 생성

cd ../
pip install wagtail
wagtail start backend
cd backend

backend라는 Wagtail project를 생성해주었다. 

 

2) 필요 모듈 설치

pip install django-rest-framework dj-rest-auth django-allauth django-cors-headers
pip install djangorestframework-simplejwt

3) App 생성

python manage.py startapp social_login

4) views.py 수정

Wagtail에서는 views.py을 사용하지 않으므로 이후 수정이 필요하다고 생각된다. 허나 지금은 튜토리얼대로 그대로 따라해볼 생각이다.

backend/social_login/views.py

from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from dj_rest_auth.registration.views import SocialLoginView
from allauth.socialaccount.providers.oauth2.client import OAuth2Client
from django.conf import settings

class GoogleLogin(SocialLoginView):
    authentication_classes = [] # disable authentication
    adapter_class = GoogleOAuth2Adapter
    callback_url = "http://localhost:3000/login"
    client_class = OAuth2Client

5) urls.py 수정

backend/backend/urls.py

from django.contrib import admin
from django.urls import path, include
from social_login.views import GoogleLogin

urlpatterns = [
    path('admin/', admin.site.urls),
    path('auth/', include('dj_rest_auth.urls')),
    path('social-login/google/', GoogleLogin.as_view(), name='google_login'),
]

6) settings/base.py 수정

backend/settings/base.py

INSTALLED_APPS = [
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     "social_login",
     "rest_framework",
     "rest_framework.authtoken",
     "corsheaders",
     "django.contrib.sites",
     # Auth & social auth
     "dj_rest_auth",
     "allauth",
     "allauth.account",
     "dj_rest_auth.registration",
     "allauth.socialaccount",
     "allauth.socialaccount.providers.google",
 ]
 
SOCIALACCOUNT_PROVIDERS = {
    'google': {
        'SCOPE': [
            'profile',
            'email',
        ],
        'AUTH_PARAMS': {
            'access_type': 'online',
        }
    }
}

# Disable email verification since this is just a test.
# If you want to enable it, you'll need to configure django-allauth's email confirmation pages
SOCIALACCOUNT_EMAIL_VERIFICATION = "none"
SOCIALACCOUNT_EMAIL_REQUIRED = False

REST_USE_JWT = True

SITE_ID = 1

from datetime import timedelta

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
    'ROTATE_REFRESH_TOKENS': True, # IMPORTANT
    'BLACKLIST_AFTER_ROTATION': True, # IMPORTANT
    'UPDATE_LAST_LOGIN': True,
}

MIDDLEWARE = [
    "corsheaders.middleware.CorsMiddleware",
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

# Rest Settings
REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework.authentication.BasicAuthentication",
        "rest_framework.authentication.SessionAuthentication",
        "dj_rest_auth.utils.JWTCookieAuthentication",
    ),
}

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

7) migrations 실행

python manage.py makemigrations
python manage.py migrate

3. Google OAuth 설정

1) Google Cloud Platform 접속

https://console.cloud.google.com/apis/dashboard

위 사이트로 이동하자. 

 

2) OAuth 설정

이후 외부를 클릭한 뒤, 앱 이름, 이메일을 입력하고 저장하기를 누른다. 

동의가 완료 되었으면 사용자 인증 정보를 클릭한다. 

OAuth 클라이언트 ID를 클릭하고 애플리케이션 유형을 웹 애플리케이션으로 설정한다. (이름은 알아서 설정)

URI 설정은 다음과 같이 하고 저장을 누른다. 

 

 

그러면 자신의 클라이언트 ID와 비밀번호가 나올 것이다. 메모장에다가 저장해놓자. 

 

 

4. Nuxt 앱에 Google 클라이언트 ID 추가

클라이언트 ID 추가

frontend/nuxt.config.js

  auth: {
    strategies: {
      google: {
        clientId: '클라이언트 ID',
        codeChallengeMethod: '',
        responseType: 'code',
        endpoints: {
          token: 'http://localhost:8000/social-login/google/',
          userInfo: 'http://localhost:8000/auth/user/'
        },
      },
    }
  },

클라이언트 ID는 아까 google에서 생성한 클라이언트 ID를 넣으면 된다. 

 

 

5. Django 앱에 Google 클라이언트 ID 및 비밀번호 추가

1) create superuser 

cd backend
python manage.py createsuperuser
Username (leave blank to use 'fadhil'): admin
Email address: admin@test.com
Password: 
Password (again): 
Superuser created successfully.

슈퍼 유저를 생성해주자. 

 

2) django-admin 페이지 접속

localhost:8000/django-admin으로 접속한다. 

로그인을 한 뒤 

다음과 같이 설정을 진행해준다. 

이제 완료되었다. 로그인을 진행한 뒤 wagtail admin으로 들어가보면 user가 등록되어 있을 것이다. 

 

'Back-End > Wagtail, Django' 카테고리의 다른 글

Wagtail BaseSetting  (0) 2021.11.15
Wagtail Debug Toolbar(+ Django)  (0) 2021.11.13
Wagtail Rich Editor 기능 추가  (0) 2021.11.06
Wagtail Admin Page 한글 설정  (0) 2021.11.04
Wagtail Form  (0) 2021.11.02

Wagtail은 Django base로 만들어진 CMS이므로 user 관리가 Django랑 같다.

바로 allauth를 사용하면 된다. 순서대로 실행해보자

 

1. All Auth 설치, Setting

$ pip install django-allauth

 

이후에 settings/base.py를 다음과 같이 추가하고 수정해준다. 

# base.py

TEMPLATES = [
    {
        # ...,
        'OPTIONS': {
            'context_processors': [
                # ...
                'django.template.context_processors.request', # <- this is the one you NEED to include
                # ...
            ],
        },
    },
]

Allauth backend 인증을 위해 추가해준다. 

# base.py 

# Authentication Backends
AUTHENTICATION_BACKENDS = (
    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',
)

Authentications_backend는 Django에서 back를 어떻게 사용할지 정보를 적어주는 곳이다. 

 

'django.contrib.auth.backends.ModelBackend'는 All auth와 상관없이 username으로 Django admin에 로그인 하기 위해 사용한다고 한다. 

 

'allauth.account.auth_backends.AuthenticationBackend' 이메일 로그인과 같이 구체적인 로그인 방법을 위해 사용한다고 한다.

 

자세한 내용을 아래 문서를 참고하자

https://docs.djangoproject.com/en/3.2/ref/contrib/auth/#authentication-backends-reference

 

그리고 allauth 기능을 사용하기 위해서 6가지를 추가해줘야한다. 

# base.py 

INSTALLED_APPS = (
    # ... other apps 

    # The following apps are required:
    'django.contrib.auth',
    'django.contrib.messages',
    'django.contrib.sites',

    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    # ...
)

그리고 base.py에 다음과 같은 내용을 추가시켜준다.

# base.py 

SITE_ID = 1

DEFAULT_AUTO_FIELD='django.db.models.AutoField'

SITE_ID는 우리가 사용할 사이트가 단일 사이트면 1을 입력해주면 된다. 자세한 내용은

https://stackoverflow.com/questions/25468676/django-sites-model-what-is-and-why-is-site-id-1 에서 확인할 수 있다.

 

마지막으로 urls.py에 urlpatterns에 다음을 추가한다. 

# urls.py

urlpatterns = [
    # .. Existing urls 
    path('accounts/', include('allauth.urls')), # Creates urls like yourwebsite.com/login/
  
    # Wagtail URLs
    path('', include(wagtail_urls)),
]

이후에 migrate를 진행하면 정상적으로 적용이 될 것이다. 다만 여기에서 migrations 충돌이 일어났는데 기존 migrations을 초기화 시켜주고 다시 실행하니 정상적으로 작동하였다. 

 

로그인 접속 url은 accounts/login으로 접속하면 된다. 

 

Login 관련하여 여러가지 옵션을 선택할 수 있는데 관련 내용은 allauth 공식 문서에 정리 되어 있다.

https://django-allauth.readthedocs.io/en/latest/configuration.html

 

참고로 몇가지 적용한걸 보자면 

# base.py 

LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL = '/'
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
ACCOUNT_LOGOUT_ON_GET = True
ACCOUNT_LOGIN_ON_PASSWORD_RESET = True
ACCOUNT_LOGOUT_REDIRECT_URL = '/login/'
ACCOUNT_PRESERVE_USERNAME_CASING = False
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False
ACCOUNT_USERNAME_BLACKLIST = ["admin", "god"]
ACCOUNT_USERNAME_MIN_LENGTH = 2

변수명만 봐도 어떤 기능을 하는지 이해가 될 것이다. 

 

2. Google 로그인 설정

구글 로그인을 설정하려면 몇가지를 추가해주면 된다. 

settings/base.py

INSTALLED_APPS = [
 
    'allauth.socialaccount.providers.google',
]

google로 로그인기능을 활성화 시키려면 위와 같이 입력하면된다. 

 

그리고 구글 로그인의 ID값 하고 Key 값을 적어야한다. 

http://127.0.0.1:8000/django-admin/ 으로 접속한다. 

 

Social applications에서 add 버튼을 누르고 

 

위와 같이 설정을 해주면 완료된다. sites가 example.com이라고 되어 있으면 Sites로 가서 이름을 바꿔주면 된다. 이 사이트가 우리가 settings.py에서 설정한 SITE_ID = 1 이다. (1번째 사이트)

 

Client id와 Secret Key은

 

구글은 https://console.developers.google.com/apis/credentials

네이버는 https://developers.naver.com/products/login/api/api.md 

 

3. template 작성

{% load socialaccount %}

<a class="button" href="{% provider_login_url 'google' %}"><strong>로그인</strong></a>

template에서는 위와 같이 작성 해주면 된다.

(네이버일 경우에는 google을 naver로만 바꿔주면 된다.)

만약 social 로그인을 사용하지 않을 것이라면 href="accounts/login"으로 해주면 된다. 

 

참고) settings/base.py에 다음과 같은 설정을 해주면 로그아웃을 할 때 accounts 페이지 이동없이 바로 로그아웃 된다.

ACCOUNT_LOGOUT_ON_GET = True
<a class="button" href="{% url 'account_logout' %}"><span>로그 아웃</span></a>

'Back-End > Wagtail, Django' 카테고리의 다른 글

Wagtail 중첩 StreamField  (0) 2021.09.01
Wagtail Custom User Field  (0) 2021.09.01
Wagtail Docker 사용 방법  (0) 2021.08.18
Wagtail demo site (breads)  (0) 2021.08.17
Wagtail demo site (blog)  (0) 2021.08.17

+ Recent posts