[Django] clone instagram #7

์ •๋ณด๊ตฌ๋‹ˆยท2021๋…„ 12์›” 6์ผ
0

Django

๋ชฉ๋ก ๋ณด๊ธฐ
15/15
post-thumbnail

ํšŒ์›๊ฐ€์ž… API ๋งŒ๋“ค๊ธฐ


ajax๋ฅผ ํ†ตํ•ด ์‹ค์ œ๋กœ ํšŒ์›๊ฐ€์ž…ํ•˜๋Š” API๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๋„๋ก ํ•˜๊ฒ ๋‹ค.

password๋Š” ์•”ํ˜ธํ™”๋ฅผ ํ•˜์—ฌ DB์— ์ €์žฅํ•œ๋‹ค.

์•”ํ˜ธํ™”์—๋Š” ๋‹จ๋ฐฉํ–ฅ/์–‘๋ฐฉํ–ฅ์ด ์žˆ๋Š”๋ฐ,
์ด๋•Œ ๋‹จ๋ฐฉํ–ฅ์€ ์•”ํ˜ธํ™” ์‹œํ‚จ ํ›„ ๋‹ค์‹œ ์›๋ž˜ ๋ชจ์Šต์œผ๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์—†๊ณ ,
์–‘๋ฐฉํ–ฅ์€ ์•”ํ˜ธํ™” ์‹œํ‚จ ํ›„ ๋‹ค์‹œ ์›๋ž˜ ๋ชจ์Šต์œผ๋กœ '๋ณตํ˜ธํ™”'๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ด๋•Œ password๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ๋ณตํ˜ธํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉด ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค !

์•ž์—์„œ ์žฅ๊ณ  ์œ ์ €๋ชจ๋ธ์—์„œ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ password ๊ธฐ๋ณธ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค๊ณ  ํ–ˆ๋‹ค.

์ด ๊ธฐ๋ณธํ•จ์ˆ˜์ธ make_password๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ password๋ฅผ ์•”ํ˜ธํ™”์‹œ์ผœ์ค€ ๋’ค DB์— ์ €์žฅํ•ด์ฃผ๋„๋ก ํ•˜๊ฒ ๋‹ค.


user/views.py

from django.contrib.auth.hashers import make_password
from rest_framework.response import Response
from .models import User


class Join(APIView):
    ...
    
    def post(self, request):
        # ํšŒ์›๊ฐ€์ž…
        email = request.data.get('email', None)
        nickname = request.data.get('nickname', None)
        name = request.data.get('name', None)
        password = request.data.get('password', None)

        # User DB ๋งŒ๋“ค์–ด ์ฃผ๊ธฐ
        User.objects.create(email=email,
                            nickname=nickname,
                            name=name,
                            password=make_password(password),  # password๊ฐ€ ์•”ํ˜ธํ™”๋˜์–ด ์ €์žฅ
                            profile="default_profile.jpg")
        
        return Response(status=200)



๊ฐ€์ž… ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ๋งŒ๋“ค๊ธฐ

templates/join.html

html

...
<div class="form-floating mb-3">
  <input style="width: 300px; height: 24px; margin: auto;" type="email" class="form-control" id="input-email" placeholder="name@example.com">
  <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="input-email">ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ ๋˜๋Š” ์ด๋ฉ”์ผ ์ฃผ์†Œ</label>
</div>

<div class="form-floating mb-3">
  <input style="width: 300px; height: 24px; margin: auto;" type="text" class="form-control" id="input-name" placeholder="name@example.com">
  <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="input-name">์ด๋ฆ„</label>
</div>

<div class="form-floating mb-3">
  <input style="width: 300px; height: 24px; margin: auto;" type="text" class="form-control" id="input-nickname" placeholder="name@example.com">
  <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="input-nickname">๋‹‰๋„ค์ž„</label>
</div>

<div class="form-floating mb-3">
  <input style="width: 300px; height: 24px; margin: auto;" type="text" class="form-control" id="input-password" placeholder="name@example.com">
  <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="input-password">๋น„๋ฐ€ ๋ฒˆํ˜ธ</label>
</div>

<button id="join-button" style="width: 300px; height: 32px; margin: auto; font-size: 14px; font-weight: bolder; margin-top: 8px;" type="button" class="btn btn-primary">๊ฐ€์ž…</button>
...

js

$('#join-button').click(function(){  // ๊ฐ€์ž…ํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด

                let email = $('#input-email').val();
                let nickname = $('#input-nickname').val();
                let name = $('#input-name').val();
                let password = $('#input-password').val();

                console.log(email, nickname, name, password)
});

id๊ฐ’์„ ์„ค์ •ํ•ด ์ค€๋’ค, ์ œ์ด์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€์ž…๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ์ฃผ์—ˆ๋‹ค.



๋ฐ์ดํ„ฐ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด์ฃผ๊ธฐ

์ด์ œ ๋‹ด์€ ๋ฐ์ดํ„ฐ๋ฅผ ajax๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ๋ณด๋‚ด์ฃผ๋„๋ก ํ•˜๊ฒ ๋‹ค.

templates/join.html

js

$.ajax({
      url: "/user/join",
      data: {
              email : email,
              nickname : nickname,
              name : name,
              password : password
            },
      method: "POST",
      success: function (data) {
        console.log("์„ฑ๊ณต");
        alert("ํšŒ์›๊ฐ€์ž… ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค. ๋กœ๊ทธ์ธ์„ ํ•ด์ฃผ์„ธ์š”.");
        location.replace('/user/login');
      },
      error: function (request, status, error) {
        console.log("์—๋Ÿฌ");
      },
      complete: function() {
        console.log("์™„๋ฃŒ");
      }
})

์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ  ํšŒ์›๊ฐ€์ž…๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด DB์— ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.




๋กœ๊ทธ์ธ API ๋งŒ๋“ค๊ธฐ


ํšŒ์›๊ฐ€์ž…์„ ๋งŒ๋“ค์–ด ์ค€ ๋’ค ๋กœ๊ทธ์ธํ•˜๋Š” API๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ๋„๋ก ํ•˜๊ฒ ๋‹ค.

๋จผ์ € ๋ทฐ๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค.

user/views.py

class Login(APIView):
...
    def post(self, request):
        # ๋กœ๊ทธ์ธ
        email = request.data.get('email', None)
        password = request.data.get('password', None)

        user = User.objects.filter(email=email).first()  # email์€ unique์ •๋ณด๋กœ, ์žˆ์œผ๋ฉด ๋ฌด์กฐ๊ฑด 1๊ฐœ์ด๊ธฐ ๋•Œ๋ฌธ์— fist()๋ฅผ ์‚ฌ์šฉํ•ด ์ฒซ๋ฒˆ์งธ ๊ฐ’๋งŒ ๊บผ๋‚ด์˜จ๋‹ค.

        if user is None:  # ํ•ด๋‹น ์ด๋ฉ”์ผ์ด User ๋””๋น„์— ์—†๋Š” ๊ฒฝ์šฐ ์—๋Ÿฌ ๋ฐ˜ํ™˜
            return Response(status=400, data=dict(message="ํšŒ์›์ •๋ณด๊ฐ€ ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค."))  # ์—๋Ÿฌ๋ฉ”์„ธ์ง€๋ฅผ '์—†์Šต๋‹ˆ๋‹ค๊ฐ€' ์•„๋‹Œ '์ž˜๋ชป๋˜์—ˆ๋‹ค๊ณ ' ํ•˜๋Š” ์ด์œ ๋Š” ํ•ด์ปค์—๊ฒŒ ๋„์›€์„ ์ฃผ์ง€ ์•Š๊ธฐ ์œ„ํ•ด์„œ

        if user.check_password(password):  # ํ•ด๋‹น ์ด๋ฉ”์ผ์ด User ๋””๋น„์— ์žˆ๋Š” ๊ฒฝ์šฐ password๋ฅผ ๋น„๊ต
            # todo ๋กœ๊ทธ์ธ ์„ฑ๊ณต. ์„ธ์…˜ or ์ฟ ํ‚ค์— ๋„ฃ์Œ
            return Response(status=200)  # ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋งž์„ ๊ฒฝ์šฐ, ๋กœ๊ทธ์ธ ์„ฑ๊ณต
        else:  # ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํ‹€๋ฆฐ๊ฒฝ์šฐ, ์—๋Ÿฌ๋ฉ”์„ธ์ง€ ๋ฐ˜ํ™˜
            return Response(status=404, data=dict(message="ํšŒ์›์ •๋ณด๊ฐ€ ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค."))



๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ๋งŒ๋“ค๊ธฐ

templates/login.html

html

...
<div class="form-floating mb-3">
  <input style="width: 300px; height: 24px; margin: auto;" type="email" class="form-control" id="input-email" placeholder="name@example.com">
  <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="input-email">ํœด๋Œ€ํฐ ๋ฒˆํ˜ธ ๋˜๋Š” ์ด๋ฉ”์ผ ์ฃผ์†Œ</label>
</div>

<div class="form-floating mb-3">
  <input style="width: 300px; height: 24px; margin: auto;" type="text" class="form-control" id="input-password" placeholder="name@example.com">
  <label style="font-size: 13px; padding: 4px 10px; margin-left: 30px; margin-top: 2px;" for="input-password">๋น„๋ฐ€ ๋ฒˆํ˜ธ</label>
</div>

<button id="login-button" style="width: 300px; height: 32px; margin: auto; font-size: 14px; font-weight: bolder; margin-top: 8px;" type="button" class="btn btn-primary">๋กœ๊ทธ์ธ</button>
...

js

$('#login-button').click(function(){  // ๊ฐ€์ž…ํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด

    let email = $('#input-email').val();
    let password = $('#input-password').val();

    console.log(email, password)
});

id๊ฐ’์„ ์„ค์ •ํ•ด ์ค€๋’ค, ์ œ์ด์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ์ฃผ์—ˆ๋‹ค.



๋ฐ์ดํ„ฐ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด์ฃผ๊ธฐ

๋‹ด์€ ๋ฐ์ดํ„ฐ(email,password)๋ฅผ ajax๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„๋ฅผ ๋ณด๋‚ด์ฃผ๋„๋ก ํ•˜๊ฒ ๋‹ค.

templates/login.html

js

$.ajax({
      url: "/user/login",
      data: {
              email : email,
              password : password
            },  
      method: "POST",
      success: function (data) {
        console.log("์„ฑ๊ณต");
        alert("๋กœ๊ทธ์ธ ์„ฑ๊ณตํ–ˆ์Šต๋‹ˆ๋‹ค.");
        location.replace('/main');  // ๋กœ๊ทธ์ธ ์„ฑ๊ณต์‹œ mainํŽ˜์ด์ง€๋กœ ์ด๋™
      },
      error: function (request, status, error) {
        console.log("์—๋Ÿฌ");
      },
      complete: function() {
        console.log("์™„๋ฃŒ");
      }
})

์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด ๊ฐ€์ž…ํ•œ ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•Œ๋งž๊ฒŒ ์ž…๋ ฅํ•˜๋ฉด ๋กœ๊ทธ์ธ ๋˜๊ณ , main ํŽ˜์ด์ง€๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.



7:36:10

0๊ฐœ์˜ ๋Œ“๊ธ€