Skip to content

d2doo/mses

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

28 Commits
ย 
ย 
ย 
ย 

Repository files navigation

MSES SERVICE

์ด ํ”„๋กœ์ ํŠธ๋Š” Django๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ๋ฐ ์†Œ์…œ ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค.


๋ชฉ์ฐจ

  1. ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ
  2. ์„ค์น˜ ๋ฐ ์‹คํ–‰ ๋ฐฉ๋ฒ•
  3. ํ”„๋กœ์„ธ์Šค ํ๋ฆ„
  4. ์ฃผ์š” ์ฝ”๋“œ ์„ค๋ช…
  5. ์ฐธ๊ณ  ์ž๋ฃŒ

ํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

MSES SERVICE๋Š” ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ๊ณผ OAuth2.0 ๊ธฐ๋ฐ˜ ์†Œ์…œ ๋กœ๊ทธ์ธ(์นด์นด์˜ค, ๋„ค์ด๋ฒ„)์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ๊ธฐ๋Šฅ

  1. ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ

    • ์‚ฌ์šฉ์ž ์ •์˜ ๋ชจ๋ธ๊ณผ Django ์ธ์ฆ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•œ ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ
  2. OAuth2.0 ๊ธฐ๋ฐ˜ ์†Œ์…œ ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ

    • ์นด์นด์˜ค, ๋„ค์ด๋ฒ„ ์†Œ์…œ ๋กœ๊ทธ์ธ ์ œ๊ณต

๋ถ€๊ฐ€ ๊ธฐ๋Šฅ

  1. ๋กœ๊ทธ์•„์›ƒ

    • ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜์„ ์ข…๋ฃŒํ•˜๊ณ  /users/landing์œผ๋กœ ์ด๋™
  2. ์ด๋ฉ”์ผ ์ค‘๋ณต ์ฒ˜๋ฆฌ

    • ๋™์ผ ์ด๋ฉ”์ผ์ด ์—ฌ๋Ÿฌ ๊ณ„์ •์—์„œ ์‚ฌ์šฉ๋  ๊ฒฝ์šฐ ๊ณ„์ •์„ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด ๊ด€๋ฆฌ
    • ์˜ˆ์‹œ:
      • ์นด์นด์˜ค ๊ณ„์ •์˜ ์ด๋ฉ”์ผ๊ณผ ๋„ค์ด๋ฒ„ ๊ณ„์ •์˜ ์ด๋ฉ”์ผ์ด ๊ฐ™์œผ๋ฉด, ๋จผ์ € ์ƒ์„ฑ๋œ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ
      • ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ์‹œ, ์ด๋ฏธ ๋™์ผํ•œ ์ด๋ฉ”์ผ๋กœ ๋“ฑ๋ก๋œ ์†Œ์…œ ๊ณ„์ •์ด ์žˆ์œผ๋ฉด ํšŒ์›๊ฐ€์ž… ๋ถˆ๊ฐ€
  3. ์ ‘๊ทผ ๊ถŒํ•œ ๊ด€๋ฆฌ

    • ๋กœ๊ทธ์ธ ์ƒํƒœ์— ๋”ฐ๋ผ ํŠน์ • URL ์ ‘๊ทผ์„ ์ œํ•œ.
    • ์˜ˆ์‹œ:
      • ๋กœ๊ทธ์•„์›ƒ ์ƒํƒœ์—์„œ /users/userinfo ์ ‘๊ทผ ๋ถˆ๊ฐ€ โ†’ /users/landing์œผ๋กœ ์ด๋™
      • ๋กœ๊ทธ์ธ ์ƒํƒœ์—์„œ /users/landing ์ ‘๊ทผ ๋ถˆ๊ฐ€ โ†’ /users/userinfo๋กœ ์ด๋™

์„ค์น˜ ๋ฐ ์‹คํ–‰ ๋ฐฉ๋ฒ•

Visual Studio Code(VSCode)์˜ ํ„ฐ๋ฏธ๋„(bash)์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  1. ๋ ˆํฌ์ง€ํ† ๋ฆฌ ํด๋ก :

    git clone https://github.com/d2doo/mses.git
    cd ./mses/be/
  2. ๊ฐ€์ƒํ™˜๊ฒฝ ์„ค์ • ๋ฐ ์˜์กด์„ฑ ์„ค์น˜:

    • ๊ฐ€์ƒํ™˜๊ฒฝ ์ƒ์„ฑ:
      python -m venv venv
    • ๊ฐ€์ƒํ™˜๊ฒฝ ํ™œ์„ฑํ™”:
      • Windows:

        source venv\Scripts\activate

        ํ˜น์€

        venv\Scripts\activate
    • ์˜์กด์„ฑ ์„ค์น˜:
      pip install -r requirements.txt
  3. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •:

    • .env ํŒŒ์ผ ์œ„์น˜: ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ(์˜ˆ: manage.py์™€ ๋™์ผํ•œ ์œ„์น˜)์— .env ํŒŒ์ผ ์ƒ์„ฑ
    • .env ํŒŒ์ผ์€ ๋ณด์•ˆ ์ƒ ์ด๋ฉ”์ผ์— ์ฒจ๋ถ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  4. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜:

    python manage.py makemigrations
    python manage.py migrate
  5. ์„œ๋ฒ„ ์‹คํ–‰:

    python manage.py runserver

ํ”„๋กœ์„ธ์Šค ํ๋ฆ„

1. ํšŒ์›๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ

์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž…

  1. GET ์š”์ฒญ:

    • ํด๋ผ์ด์–ธํŠธ๊ฐ€ /users/signup ๊ฒฝ๋กœ๋กœ ์ ‘๊ทผ
    • Django๋Š” ๋นˆ ํšŒ์›๊ฐ€์ž… ํผ์„ ๋ Œ๋”๋งํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ œ๊ณต
  2. POST ์š”์ฒญ:

    • ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†ก
    • Django๋Š” ์ „๋‹ฌ๋œ ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆ
      • ์œ ํšจ์„ฑ ๊ฒ€์ฆ ์‹คํŒจ ์‹œ: ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ํผ ์žฌ์ „์†ก
      • ์œ ํšจ์„ฑ ๊ฒ€์ฆ ์„ฑ๊ณต ์‹œ: ์ƒˆ ์‚ฌ์šฉ์ž ๊ณ„์ •์„ ์ƒ์„ฑ
    • ๊ณ„์ • ์ƒ์„ฑ ํ›„:
      • ์‚ฌ์šฉ์ž ์ž๋™ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ
      • ์‚ฌ์šฉ์ž ์ •๋ณด ํŽ˜์ด์ง€(/users/userinfo/)๋กœ ์ด๋™

์†Œ์…œ ๋กœ๊ทธ์ธ (OAuth2.0)

  1. ์†Œ์…œ ๋กœ๊ทธ์ธ ์š”์ฒญ:

    • ์‚ฌ์šฉ์ž๊ฐ€ ์นด์นด์˜ค/๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญ
    • ํ•ด๋‹น ์†Œ์…œ ํ”Œ๋žซํผ์˜ ์ธ์ฆ ํŽ˜์ด์ง€๋กœ ์ด๋™
  2. OAuth2.0 ์ธ์ฆ:

    • ์‚ฌ์šฉ์ž๊ฐ€ ์†Œ์…œ ํ”Œ๋žซํผ์—์„œ ์ธ์ฆ ์Šน์ธ
    • ์ธ์ฆ์ด ์™„๋ฃŒ๋˜๋ฉด, Django allauth๊ฐ€ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ๋ฐ›์•„ ์ฝœ๋ฐฑ URL๋กœ ์ฒ˜๋ฆฌ
  3. ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ:

    • Django allauth๊ฐ€ ์†Œ์…œ ํ”Œ๋žซํผ์—์„œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ด
    • ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ populate_user ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰:
      • ์‚ฌ์šฉ์ž์˜ ๋ฐ์ดํ„ฐ(๋‹‰๋„ค์ž„, ํ”„๋กœํ•„ ์ด๋ฏธ์ง€, ์ด๋ฉ”์ผ, ๋ณ„๋ช…, ์ƒ์ผ) ์ €์žฅ
      • ๊ธฐ์กด ๋™์ผ ์ด๋ฉ”์ผ์˜ ๊ณ„์ •์ด ์กด์žฌํ•  ๊ฒฝ์šฐ
        • ๊ณ„์ • ์—ฐ๊ฒฐ
        • ๋กœ๊ทธ์ธ ํ›„ ์‚ฌ์šฉ์ž ์ •๋ณด ํŽ˜์ด์ง€(/users/userinfo/)๋กœ ์ด๋™

2. ์‚ฌ์šฉ์ž ์ •๋ณด ์ ‘๊ทผ

๋กœ๊ทธ์ธ ์ƒํƒœ์— ๋”ฐ๋ฅธ URL ์ ‘๊ทผ ์ œํ•œ

  1. ๋กœ๊ทธ์•„์›ƒ ์ƒํƒœ:

    • /users/userinfo/ ์ ‘๊ทผ ์‹œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€(/users/landing/)๋กœ ์ด๋™
  2. ๋กœ๊ทธ์ธ ์ƒํƒœ:

    • /users/landing/ ์ ‘๊ทผ ์‹œ ์‚ฌ์šฉ์ž ์ •๋ณด ํŽ˜์ด์ง€(/users/userinfo/)๋กœ ์ด๋™
    • ์ด๋ฏธ ๋กœ๊ทธ์ธ๋œ ์ƒํƒœ์—์„œ ๋ถˆํ•„์š”ํ•œ ํšŒ์›๊ฐ€์ž…/๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ํ‘œ์‹œ ๋ฐฉ์ง€

3. ์ด๋ฉ”์ผ ์ค‘๋ณต ์ฒ˜๋ฆฌ

์†Œ์…œ ๋กœ๊ทธ์ธ๊ณผ ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ๊ฐ„ ์ด๋ฉ”์ผ ์ค‘๋ณต

  1. ์‹œ๋‚˜๋ฆฌ์˜ค 1:

    • ์นด์นด์˜ค ๊ณ„์ •๊ณผ ๋„ค์ด๋ฒ„ ๊ณ„์ •์˜ ์ด๋ฉ”์ผ์ด ๋™์ผํ•œ ๊ฒฝ์šฐ
    • ๋™์ผ ์ด๋ฉ”์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ์†Œ์…œ ๊ณ„์ • ๋กœ๊ทธ์ธ ์‹œ, ๊ธฐ์กด ๊ณ„์ •๊ณผ ์—ฐ๊ฒฐ
  2. ์‹œ๋‚˜๋ฆฌ์˜ค 2:

    • ๋™์ผ ์ด๋ฉ”์ผ๋กœ ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ์‹œ๋„
    • ์ด๋ฏธ ์‚ฌ์šฉ ์ค‘์ธ ์ด๋ฉ”์ผ๋กœ๋Š” ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ๋ถˆ๊ฐ€

4. ์ „์ฒด ํ๋ฆ„ ์š”์•ฝ

  1. ํšŒ์›๊ฐ€์ž…/๋กœ๊ทธ์ธ ์š”์ฒญ โ†’ ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ โ†’ ๊ณ„์ • ์ƒ์„ฑ/๋กœ๊ทธ์ธ โ†’ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
  2. OAuth2.0 โ†’ ์ธ์ฆ ๋ฐ ์‚ฌ์šฉ์ž ์ •๋ณด ์ฒ˜๋ฆฌ โ†’ ๊ธฐ์กด ๊ณ„์ •๊ณผ ์—ฐ๊ฒฐ/์ƒˆ ๊ณ„์ • ์ƒ์„ฑ
  3. ๋กœ๊ทธ์ธ ์ƒํƒœ โ†’ URL ์ ‘๊ทผ ์ œํ•œ ๋ฐ ๋ณดํ˜ธ

์ฃผ์š” ์ฝ”๋“œ ์„ค๋ช…

Django์˜ allauth ํŒจํ‚ค์ง€์™€ Django ๊ธฐ๋ณธ auth ์‹œ์Šคํ…œ์„ ํ™œ์šฉํ•˜์—ฌ ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ๋ฐ OAuth2.0 ๊ธฐ๋ฐ˜ ์†Œ์…œ ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž…: ์‚ฌ์šฉ์ž ์ •์˜ ๋ชจ๋ธ(User)์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅ
  • ์†Œ์…œ ๋กœ๊ทธ์ธ: django-allauth๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ OAuth2.0 ๊ธฐ๋ฐ˜ ๋กœ๊ทธ์ธ(Kakao, Naver)์„ ์ฒ˜๋ฆฌ
  • ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž…๊ณผ ์†Œ์…œ ๋กœ๊ทธ์ธ์€ ๋…๋ฆฝ์ ์œผ๋กœ ๊ด€๋ฆฌ๋˜๋ฉฐ, ๋™์ผ ์ด๋ฉ”์ผ ์‚ฌ์šฉ ์‹œ ๊ณ„์ •์„ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•˜๋„๋ก ์„ค๊ณ„

models.py

User ๋ชจ๋ธ์€ Django์˜ ๊ธฐ๋ณธ ์‚ฌ์šฉ์ž ๋ชจ๋ธ์„ ํ™•์žฅํ•œ ์ปค์Šคํ…€ ์‚ฌ์šฉ์ž ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค.
์†Œ์…œ ๋กœ๊ทธ์ธ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ(์ด๋ฉ”์ผ, ๋‹‰๋„ค์ž„)๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•„๋“œ๋ฅผ ํ™•์žฅํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ:

from django.contrib.auth.models import AbstractUser
from django.db import models

# User ์ปค์Šคํ…€
class User(AbstractUser):
    email = models.EmailField(unique=True)  # ์ด๋ฉ”์ผ (unique ์„ค์ •)
    nickname = models.CharField(max_length=50, blank=True)  # ๋‹‰๋„ค์ž„ (์„ ํƒ ํ•„๋“œ)

    def __str__(self):
        return self.username

views.py

ํšŒ์›๊ฐ€์ž… ์ฒ˜๋ฆฌ

  • ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” signup_view ํ•จ์ˆ˜๋Š” Django ๊ธฐ๋ณธ ํผ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • ์œ ํšจํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅ๋ฐ›์œผ๋ฉด ์ƒˆ ์‚ฌ์šฉ์ž ๊ณ„์ •์„ ์ƒ์„ฑํ•˜๊ณ  ์ž๋™์œผ๋กœ ๋กœ๊ทธ์ธํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • django.shortcuts์˜ render()๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ http ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ:

from django.shortcuts import render, redirect
from django.contrib.auth import login as auth_login, get_backends
from .forms import SignupForm

def signup_view(request):
    if request.method == 'POST':
        form = SignupForm(request.POST)
        # ์œ ํšจ์„ฑ ๊ฒ€์ฆ
        if form.is_valid():
            user = form.save() # ์œ ํšจํ•œ ํผ ๋ฐ์ดํ„ฐ๋กœ ์‚ฌ์šฉ์ž ์ €์žฅ
            backend = get_backends()[0] # ์ธ์ฆ ๋ฐฑ์—”๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ
            auth_login(request, user, backend=backend.__module__ + '.' + backend.__class__.__name__) # ๋ฐฑ์—”๋“œ ์„ค์ •์œผ๋กœ ๋กœ๊ทธ์ธ
            return redirect('/users/userinfo/') # ์‚ฌ์šฉ์ž ์ •๋ณด ํŽ˜์ด์ง€๋กœ redirect
    else:
        form = SignupForm() # GET ์š”์ฒญ์‹œ ๋น„์–ด์žˆ๋Š” ํผ ์ œ๊ณต
    context = {
        'form': form
    }
    return render(request, 'signup.html', context)

OAuth2.0 ์†Œ์…œ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ

Django allauth ํŒจํ‚ค์ง€๋ฅผ ํ™œ์šฉํ•˜์—ฌ Kakao ๋ฐ Naver OAuth2.0 ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ์„ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ์†Œ์…œ ๋กœ๊ทธ์ธ์€ allauth์˜ SocialAccount ๋ชจ๋ธ์—์„œ ๊ด€๋ฆฌ๋˜๋ฉฐ, ์ผ๋ฐ˜ ํšŒ์›๊ฐ€์ž… ๋ฐ์ดํ„ฐ(User ๋ชจ๋ธ)์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
  • pre_social_login ๋ฐ populate_user ๋ฉ”์„œ๋“œ๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜์—ฌ ๋ฐ์ดํ„ฐ ํ†ตํ•ฉ ๋ฐ ์‚ฌ์šฉ์ž ์ƒ์„ฑ ๋ฐฉ์‹์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์ฝ”๋“œ

  • ์‚ฌ์šฉ์ž ๋ชจ๋ธ ๋งคํ•‘ ๋ฐ ์ƒ์„ฑ

adapters.py

Django allauth์˜ ๊ธฐ๋ณธ ์†Œ์…œ ๊ณ„์ • ์–ด๋Œ‘ํ„ฐ(DefaultSocialAccountAdapter)๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜์—ฌ Kakao ๋ฐ Naver OAuth2.0 ๋กœ๊ทธ์ธ์„ ์ฒ˜๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  1. ์†Œ์…œ ๋กœ๊ทธ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ:

    • ๊ฐ ์ œ๊ณต์ž(Kakao, Naver)์˜ ๋ฐ์ดํ„ฐ๋ฅผ populate_user ๋ฉ”์„œ๋“œ์—์„œ ๊ฐ€๊ณตํ•˜์—ฌ ์‚ฌ์šฉ์ž ๋ชจ๋ธ์— ๋งคํ•‘
    • ์ถ”์ƒ ํด๋ž˜์Šค์™€ ํŒฉํ† ๋ฆฌ ํŒจํ„ด์„ ํ™œ์šฉํ•ด ์ œ๊ณต์ž๋ณ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ๋ถ„๋ฆฌ
  2. ์ค‘๋ณต ์ด๋ฉ”์ผ ์ฒ˜๋ฆฌ:

    • pre_social_login ๋ฉ”์„œ๋“œ์—์„œ ์ค‘๋ณต๋œ ์ด๋ฉ”์ผ์„ ๊ฐ€์ง„ ๊ณ„์ •์„ ์—ฐ๊ฒฐ

์ฝ”๋“œ:

from abc import ABC, abstractmethod
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.account.models import EmailAddress
from django.shortcuts import render
from django.contrib.auth import get_user_model

User = get_user_model()

# ์†Œ์…œ ๋กœ๊ทธ์ธ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌํ•˜๋Š” ์ถ”์ƒํด๋ž˜์Šค
class SocialLoginHandler(ABC):
    @abstractmethod
    def populate_user(self, user, extra_data):
        pass

# ์นด์นด์˜ค ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ
class KakaoLoginHandler(SocialLoginHandler):
    def populate_user(self, user, extra_data):
        kakao_account = extra_data.get('kakao_account', {})
        profile = kakao_account.get('profile', {})
        user.username = profile.get('nickname', '') or f"user_{extra_data.get('id', '')}"
        user.first_name = kakao_account.get('name', '') or profile.get('nickname', '')

# ๋„ค์ด๋ฒ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ
class NaverLoginHandler(SocialLoginHandler):
    def populate_user(self, user, extra_data):
        user.username = extra_data.get('name', '') or extra_data.get('nickname', '') or f"user_{extra_data.get('id', '')}"
        user.first_name = extra_data.get('name', '') or extra_data.get('nickname', '')

# ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค
class SocialLoginHandlerFactory:
    # ์ œ๊ณต์ž ๋ณ„ ํ•ธ๋“ค๋Ÿฌ
    HANDLERS = {
        'kakao': KakaoLoginHandler,
        'naver': NaverLoginHandler,
    }

    @staticmethod
    def get_handler(provider):
        handler_class = SocialLoginHandlerFactory.HANDLERS.get(provider)
        if handler_class is None:
            raise ValueError(f"Provider '{provider}'์— ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
        return handler_class()

# django allauth ์†Œ์…œ ๊ณ„์ • ์–ด๋Œ‘ํ„ฐ ์ปค์Šคํ…€
class MySocialAccountAdapter(DefaultSocialAccountAdapter):
    # ๋กœ๊ทธ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ์ž ๋ชจ๋ธ์— ๋งคํ•‘
    def populate_user(self, request, sociallogin, data):
        user = super().populate_user(request, sociallogin, data)
        extra_data = sociallogin.account.extra_data
        provider = sociallogin.account.provider

        # ์ œ๊ณต์ž ๋ณ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ
        handler = SocialLoginHandlerFactory.get_handler(provider)
        handler.populate_user(user, extra_data)
        user.last_name = ''  # ์ดˆ๊ธฐํ™”
        return user

    # ์ค‘๋ณต ์ด๋ฉ”์ผ ๊ณ„์ • ํ†ตํ•ฉ ์ฒ˜๋ฆฌ
    def pre_social_login(self, request, sociallogin):
        if sociallogin.is_existing:
            return

        email = sociallogin.account.extra_data.get('email')
        if email:
            try:
                existing_user = EmailAddress.objects.get(email=email).user
                sociallogin.connect(request, existing_user)
            except EmailAddress.DoesNotExist:
                pass

์ฃผ์š” ๋กœ์ง ์„ค๋ช…

  1. populate_user:

    • ์†Œ์…œ ์ œ๊ณต์ž๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉ์ž ๋ชจ๋ธ์— ๋งคํ•‘
    • ํ™•์žฅ์„ฑ์„ ์œ„ํ•ด Kakao์™€ Naver ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„๋ฆฌ ์ฒ˜๋ฆฌ
  2. pre_social_login:

    • ์ค‘๋ณต ์ด๋ฉ”์ผ ํ™•์ธ ๋ฐ ๊ธฐ์กด ์‚ฌ์šฉ์ž ๊ณ„์ • ์—ฐ๊ฒฐ
    • EmailAddress ๋ชจ๋ธ์„ ํ™œ์šฉํ•ด ์ด๋ฉ”์ผ ์ค‘๋ณต ์—ฌ๋ถ€๋ฅผ ํ™•์ธ
  3. ์ถ”์ƒ ํด๋ž˜์Šค ๋ฐ ํŒฉํ† ๋ฆฌ ํŒจํ„ด:

    • SocialLoginHandler ์ถ”์ƒ ํด๋ž˜์Šค๋ฅผ ํ†ตํ•ด ๊ณตํ†ต ์ธํ„ฐํŽ˜์ด์Šค ์ •์˜
    • ํŒฉํ† ๋ฆฌ ํด๋ž˜์Šค(SocialLoginHandlerFactory)๋ฅผ ํ™œ์šฉํ•ด ์ œ๊ณต์ž๋ณ„ ๋กœ์ง์„ ๋ถ„๋ฆฌ

๋ถ€๊ฐ€๊ธฐ๋Šฅ ์„ค๋ช…

๋กœ๊ทธ์•„์›ƒ

Django ๊ธฐ๋ณธ auth ์‹œ์Šคํ…œ์˜ logout() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„

from django.urls import path
from django.contrib.auth.views import LogoutView

urlpatterns = [
    ...
    path('logout/', LogoutView.as_view(), name='logout'),
]

URL ์ ‘๊ทผ ์ œํ•œ

  • ๋กœ๊ทธ์ธ ์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํŠน์ • ํŽ˜์ด์ง€ ์ ‘๊ทผ ์ œํ•œ.
    • ์˜ˆ: ๋กœ๊ทธ์ธ ์ƒํƒœ์—์„œ /users/landing ์ ‘๊ทผ ์‹œ /user/info๋กœ ์ด๋™
    • ๋กœ๊ทธ์•„์›ƒ ์ƒํƒœ์—์„œ /users/userinfo ์ ‘๊ทผ ์‹œ /user/landing์œผ๋กœ ์ด๋™
from django.shortcuts import render, redirect
from allauth.socialaccount.models import SocialAccount

def landing_view(request):
    # ๋กœ๊ทธ์ธ ์ƒํƒœ์ธ์ง€ ํ™•์ธ ํ›„ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
    if request.user.is_authenticated:
        return redirect('/users/userinfo')
    
    return render(request, 'landing.html')

def userinfo_view(request):
    # ๋กœ๊ทธ์ธ ์ƒํƒœ์ธ์ง€ ํ™•์ธ ํ›„ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
    if not request.user.is_authenticated:
        return redirect('/users/landing')
    
    social_account = SocialAccount.objects.filter(user=request.user).first()
    extra_data = social_account.extra_data if social_account else {}
    context = {
        'extra_data': extra_data
    }
    return render(request, 'userinfo.html', context)

์ฐธ๊ณ  ์ž๋ฃŒ


์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜„

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors