JUST DO IT!

[TIL]KDT_20230427 ๋ณธ๋ฌธ

TIL

[TIL]KDT_20230427

sunhokimDev 2023. 4. 27. 17:22

๐Ÿ“š KDT WEEK 4 DAY 4 TIL

  • User ์ถ”๊ฐ€ ๋ฐ ๊ด€๋ฆฌ
  • postman

 


 

 ๐ŸŸฅ User

์ €๋ฒˆ ํ•™์Šต์—์„œ admin์„ ์ƒ์„ฑํ•  ๋•Œ, createsuperuser ๋ผ๋Š” ๋ช…๋ ์–ด๋ฅผ ํ†ตํ•ด shell์—์„œ admin์„ ๋งŒ๋“ค ์ˆ˜๊ฐ€ ์žˆ์—ˆ๋‹ค.

์ด admin์€ ํ•˜๋‚˜์˜ User Model์— ํ•ด๋‹นํ•˜๋Š”๋ฐ, ์ด๋Š” django.contrib.auth.models์— ๋ฏธ๋ฆฌ ์ •์˜๋˜์–ด ์žˆ๋Š” ๋ชจ๋ธ์ด๋‹ค.

 

์ด๋ฏธ ๋ชจ๋ธ์ด ์žˆ์œผ๋ฏ€๋กœ, ์ด๋ฅผ Question ๋ชจ๋ธ์— ์™ธ๋ž˜ํ‚ค๋กœ ๋„ฃ์–ด๋ณด์•˜๋‹ค.

owner = models.ForeignKey('auth.User', related_name='questions', on_delete=models.CASCADE, null=True)

User๋ชจ๋ธ์ด auth์— ์กด์žฌํ•˜๋ฏ€๋กœ auth.User ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

 

์—ฌ๊ธฐ์„œ related_name='questions' ์˜ ๊ธฐ๋Šฅ์€..

 

์ €๋ฒˆ์— shell์—์„œ ํ•˜๋‚˜์˜ question ์˜ค๋ธŒ์ ํŠธ์— ํ•ด๋‹นํ•˜๋Š” choice๋“ค์„ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด.. ๋ช…๋ น์–ด๋Š”

question.choice_set.all()

์„ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ related_name์„ ์ €๋ ‡๊ฒŒ ์ด๋ฆ„์œผ๋กœ ์ •์˜ํ•ด์ฃผ๋ฉด,

user.questions.all()

์œผ๋กœ๋„ ๊ฐ™์€ ๋™์ž‘์„ ํ•˜๋ฏ€๋กœ, _set ๋ถ€๋ถ„์„ ์ƒ๋žตํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค!

 

์ด๋ ‡๊ฒŒ question ๋ชจ๋ธ์„ ์ˆ˜์ •ํ•˜์˜€์œผ๋ฏ€๋กœ migration์„ ์žŠ์ง€๋ง์ž!

 


 

User Page

 

DRF๋กœ QuestionList์™€ QuestionDetail ํŽ˜์ด์ง€๋ฅผ ๊ตฌํ˜„ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ, User Page๋„ ์ž‘์„ฑํ•ด๋ณด์ž.

 

๋ฐฉ๋ฒ•๊ณผ ์ˆœ์„œ๋Š” ๋™์ผํ•˜๋‹ค. Serializer ์ž‘์„ฑ โ–ถ views.py ์ž‘์„ฑ โ–ถ urls.py ์ž‘์„ฑ

 

UserSerializer

โ–ถ polls_api/serializers.py

from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
    questions = serializers.PrimaryKeyRelatedField(many=True, queryset=Question.objects.all())
    
    class Meta:
        model = User
        fields = ['id', 'username', 'questions']

QuestionSerializer์™€ ๋‹ค๋ฅด๊ฒŒ ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด ํ•œ ์ค„ ๋” ์žˆ๋‹ค.

UserSerializer์—์„œ๋Š” 'questions' ํ•„๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด questions๋ฅผ ์œ„์—์„œ ์ •์˜ํ•ด์ค„ ํ•„์š”๊ฐ€ ์žˆ๋‹ค!

 

user.questions.all() ์ด๋‚˜question.choice_set.all() ์˜ query๋ฌธ์„ ์‚ดํŽด๋ณด๋ฉด,

ํ•ญ์ƒ WHERE๋ฌธ์—์„œ ์™ธ๋ž˜ํ‚ค๋ฅผ ์‚ฌ์šฉํ•œ ๋ชจ๋ธ์—์„œ ์™ธ๋ž˜ํ‚ค๋ฅผ ์‚ฌ์šฉ๋ฐ›์€ ๋ชจ๋ธ๋กœ id๋ฅผ ์ฐพ์•„๊ฐ€๋„๋ก ๋˜์–ด์žˆ๋‹ค.

ex) user.questions.all()์˜ ๊ฒฝ์šฐ, WHERE "polls_question"."owner_id" = 1

๋”ฐ๋ผ์„œ  'questions' ํ•„๋“œ๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ๋Š” questions๋ฅผ ๋จผ์ € ์ •์˜ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค!

 

UserList, UserDetail Page View

โ–ถ polls_api/views.py

from django.contrib.auth.models import User
from polls_api.serializers import UserSerializer

class UserList(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    
class UserDetail(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

generics์—์„œ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์„ ํƒํ•˜๊ณ  ์ƒ์†๋ฐ›์•„์ค€๋‹ค. ๋‹จ์ˆœ ์ถœ๋ ฅ์ด๋ผ๋ฉด ํ•ด๋‹น APIView๋งŒ์œผ๋กœ๋„ ์ถฉ๋ถ„ํ•˜๋‹ค.

 

โ–ถ polls_api/urls.py

urlpatterns = [
    path('users/', UserList.as_view(),name='user-list'),
    path('users/<int:pk>/', UserDetail.as_view()),
]

urls.py์— ํ•ด๋‹น path์„ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋์ด๋‹ค.

id๊ฐ€ ์•„๋‹Œ pk๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฑธ ์žŠ์ง€๋ง์ž.

 

UserList Page

 

UserDetail Page

 


 

User ์ƒ์„ฑํ•˜๊ธฐ

 

๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด์ ธ ์žˆ๋Š” UserCreationForm๊ณผ Serializer์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ฐ๊ฐ ์†Œ๊ฐœํ•˜๊ฒ ๋‹ค.

 

 

1. Form์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

โ–ถ polls/views.py

from django.views import generic
from django.urls import reverse_lazy
from django.contrib.auth.forms import UserCreationForm

class SignupView(generic.CreateView):
    form_class = UserCreationForm
    success_url = reverse_lazy('user-list') # Redirection
    template_name = 'registration/signup.html'

SignupView๋ผ๋Š” ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด views.py์— ํ•จ์ˆ˜๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.

generic์—์„œ ์ง€์›ํ•˜๋Š” ์œ ์ € ์ƒ์„ฑ Form์„ ๊ฐ€์ ธ๋‹ค ์“ธ ๊ฒƒ์ด๋ฏ€๋กœ, ์ƒ์„ฑ์— ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋“ค์„ ์„ ์–ธํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

  • UserCreationForm : ์žฅ๊ณ ์—์„œ ์ง€์›ํ•˜๋Š” ๊ธฐ๋ณธ ํšŒ์›๊ฐ€์ž… ํผ
  • reverse_lazy : url์˜ name์„ ํ†ตํ•ด Redirectionํ•  ๋•Œ ์‚ฌ์šฉํ•จ. ๋™์ž‘ ์™„๋ฃŒ ํ›„ ํ•ด๋‹น name์˜ url๋กœ ์ด๋™

์œ„ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๊ฐ€์ ธ์˜ค๊ฒ ๋‹ค๊ณ  ์„ ์–ธํ•œ signup.html์„ ์ž‘์„ฑํ•ด๋ณด์ž.

 

โ–ถ templates/registration/signup.html

<h2>ํšŒ์›๊ฐ€์ž…</h2>
<form method="post">
    {% csrf_token %}
    {{ form.as_p }} <!-- User Creation Form ์ž๋™ -->
    <button type="submit">๊ฐ€์ž…ํ•˜๊ธฐ</button>
</form>

{{form.as_p}} ๋Š” form์— ์ •์˜ํ•œ ๋ชจ๋ธ ํ•„๋“œ์— ํ•ด๋‹นํ•˜๋Š” html ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค.

 

โ–ถ polls/urls.py

urlpatterns = [
    path('signup/', SignupView.as_view(), )
]

ํ•ด๋‹น path๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์˜ url์„ ์ƒ์„ฑํ•œ๋‹ค.

 

ํ•ด๋‹น url๋กœ ์ด๋™ํ•˜๋ฉด ์ž๋™์™„์„ฑ๋œ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด ํŽ˜์ด์ง€์—์„œ๋Š” ํŒจ์Šค์›Œ๋“œ์˜ ์ œํ•œ ์‚ฌํ•ญ ๋“ฑ์˜ ๊ธฐ๋Šฅ๋„ ์ž๋™์œผ๋กœ ์ง€์›ํ•œ๋‹ค.

 

 

2. Serializer๋ฅผ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

 

โ–ถ polls_api/serializers.py

# JSON์„ ํ†ตํ•œ API ๊ตฌํ˜„์„ ํ•˜๊ณ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์šฉ์ž ๋“ฑ๋ก๋„ Serializer๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค
# UserSerializer๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์ด์œ ๋Š” ์•„๋ž˜ ํ•จ์ˆ˜๋“ค์„ ๋ชจ๋‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
class RegisterSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only = True, required = True, validators = [validate_password]) # ํŒจ์Šค์›Œ๋“œ ๊ฒ€์ฆ
    password2 = serializers.CharField(write_only = True, required = True) # ํŒจ์Šค์›Œ๋“œ๊ฐ€ ๊ฐ™์€์ง€

    def validate(self, attrs):
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError({"password" : "๋‘ ํŒจ์Šค์›Œ๋“œ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."})
        return attrs
    
    def create(self, validated_data):
        user = User.objects.create(username = validated_data['username'])
        user.set_password(validated_data['password'])
        user.save()

        return user

    class Meta:
        model = User
        fields = ['username', 'password','password2']
  • ๋ช‡ ๊ฐ€์ง€ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฏธ ๊ตฌํ˜„๋œ UserSerializer๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.
  • password์˜ 2์ฐจ ๊ฒ€์ฆ์„ ์œ„ํ•ด password2๊นŒ์ง€ ์ •์˜ํ•˜๊ณ , validate ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ผ์น˜๊ฒ€์ฆ์„ ๋™์ž‘ํ•œ๋‹ค.
  • password2์˜ ์กด์žฌ๋กœ, ๊ธฐ์กด ModelSerializer์˜ create๊ฐ€ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ createํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด์ค€๋‹ค.

โ–ถ polls_api/views.py

from polls_api.serializers import RegisterSerializer

class RegisterUser(generics.CreateAPIView):
    serializer_class = RegisterSerializer

views.py์— ๊ตฌํ˜„ํ•œ RegisterSerializer๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ view๋ฅผ ์ •์˜ํ•˜๊ณ ,

urls.py์— ์ถ”๊ฐ€ํ•œ๋‹ค.

path('register/', RegisterUser.as_view()),

 

ํ•ด๋‹น url๋กœ ์ ‘์†ํ–ˆ์„ ๋•Œ, ๊ตฌํ˜„๋œ ํŽ˜์ด์ง€์˜ ๋ชจ์Šต

 

User Login, Logout

์ถ”๊ฐ€๋กœ ๋กœ๊ทธ์ธ, ๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ๊นŒ์ง€ ๊ตฌํ˜„ํ•˜๋ ค๋ฉด.. ์ด๊ฒƒ๋„ DRF์—์„œ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์–ด ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๋จผ์ € urls.py์— ํ•˜๋‚˜์˜ path๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

path('api-auth/', include('rest_framework.urls'))

rest_framework.urls์„ ์ฐพ์•„๊ฐ€์„œ ๋“ค์—ฌ๊ฐ€๋ณด๋ฉด, ์–ด๋–ป๊ฒŒ ๋กœ๊ทธ์ธ๊ณผ ๋กœ๊ทธ์•„์›ƒ์ด ๊ตฌํ˜„๋˜๋Š”์ง€๋„ ์•Œ ์ˆ˜ ์žˆ๋‹ค!

 

๊ทธ๋ฆฌ๊ณ  mysite/settings.py์—

LOGIN_REDIRECT_URL = reverse_lazy('question-list')
LOGOUT_REDIRECT_URL = reverse_lazy('question-list')

ํ•ด๋‹น ์ด๋ฆ„์˜ ๋ณ€์ˆ˜๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜์„ ๊ตฌํ˜„ํ•ด์ฃผ๋ฉด, ๋กœ๊ทธ์ธ๊ณผ ๋กœ๊ทธ์•„์›ƒ ์ดํ›„ ํ•ด๋‹น ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค.

 

๊ตฌํ˜„๋œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ํ™”๋ฉด. URL์ด ์กฐ๊ธˆ ์ƒ๊ฐํ–ˆ๋˜ ๊ฒƒ๊ณผ๋Š” ๋‹ฌ๋ž๋‹ค.

 


 

์ƒ์„ฑํ•œ Question์˜ Owner ํ• ๋‹นํ•˜๊ธฐ

 

question-list ํŽ˜์ด์ง€ ํ•˜๋‹จ๋ถ€์— ์žˆ๋Š” question ์ƒ์„ฑ๋ถ€

 

๋กœ๊ทธ์ธ์ด ๋œ ์ƒํƒœ์—์„œ ์œ„์˜ ์ƒ์„ฑ๋ถ€๋ฅผ ํ†ตํ•ด Question ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด, Owner๋ฅผ ํ• ๋‹นํ•ด์ฃผ๋„๋ก ๋งŒ๋“ค์–ด๋ณธ๋‹ค.

 

 

โ–ถ polls_api/serializers.py

class QuestionSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')

    class Meta:
        model = Question
        fields = ['id', 'question_text', 'pub_date','owner'] # ModelSerializer๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ

ModelSerializer ๋•๋ถ„์— owner๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ๋‹ค.

fields์— owner ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , owner๋Š” ์ƒ์„ฑํ•  ๋•Œ ์„ ํƒํ•˜๊ฑฐ๋‚˜ ์ž…๋ ฅ๋˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ฏ€๋กœ Readonly์˜ต์…˜๋„ ๋ถ™์—ฌ์ค€๋‹ค.

 

โ–ถ polls_api/views.py

class QuestionList(generics.ListCreateAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly] # ๋กœ๊ทธ์ธ๋˜์–ด์žˆ์ง€ ์•Š์œผ๋ฉด readonly

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user) # ์ด๋ฏธ ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž๋ฅผ ์ง€์ •ํ•จ, owner๊ฐ€ readonly์—ฌ๋„ .save() ๋™์ž‘์—๋“  ๋ฌด์—‡์ด๋“  ๋‹ค ๋จ

 

perform_createํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•ด์„œ, ํ˜„์žฌ ๋กœ๊ทธ์ธ๋œ user๊ฐ€ owner๊ฐ€ ๋˜๋„๋ก ๊ตฌํ˜„ํ•ด์ค€๋‹ค.

์ค‘์š”ํ•œ ์ ์€, .save()๋Š” readonly ์˜ต์…˜์„ ๋ฌด์‹œํ•˜๊ณ  ๋“ค์–ด์˜จ ๊ฐ’์„ ํ• ๋‹นํ•ด์ค€ ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. id๋„ ๊ฐ€๋Šฅํ•˜๋‹ค!

๋˜ํ•œ ๋กœ๊ทธ์•„์›ƒ ์ƒํƒœ์ผ ๋•Œ, ์ฆ‰ user ์ •๋ณด๊ฐ€ ์—†์„ ๋•Œ๋Š” ์ž…๋ ฅ๋ฐ›์ง€ ์•Š์•„์•ผ ํ•˜๋ฏ€๋กœ permission_classes๋ฅผ ์œ„์ฒ˜๋Ÿผ ์ •์˜ํ•ด์ค€๋‹ค.

 

์ถ”๊ฐ€๋กœ user๋Š” ์ž๊ธฐ๊ฐ€ ๋งŒ๋“  question๋งŒ ์ˆ˜์ •์ด ๊ฐ€๋Šฅํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ permissions.py๋ฅผ ๋งŒ๋“ค์–ด ์ •์˜ํ•ด์ค€๋‹ค.

 

โ–ถ polls_api/permissions.py

from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS: # SAFE_METHODS = ('GET', 'HEAD', 'OPTIONS') read_only๋Š” ํ•ญ์ƒ ํ—ˆ์šฉ
            return True
        
        return obj.owner == request.user # ์˜ค๋ธŒ์ ํŠธ์˜ ์†Œ์œ ์ž๊ฐ€ ์š”์ฒญํ•œ ์‚ฌ์šฉ์ž ์ธ๊ฐ€? ๋งž์œผ๋ฉด True

์ด๋ ‡๊ฒŒ ๋”ฐ๋กœ permission.py๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋‚ด๊ฐ€ ํ•„์š”ํ–ˆ๋˜ ๊ธฐ๋Šฅ์„ ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„ํ•ด๋‘๊ณ ..

 

 

โ–ถ polls_api/views.py

class QuestionDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]

permission์„ ์‚ฌ์šฉํ•˜๋Š” views.py์˜ ํ•ด๋‹น ํŽ˜์ด์ง€ permission_classes์— ์œ„์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•œ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค!

 

 


 

๐ŸŸฆ ๊ฐ„๋‹จํžˆ postman ์‚ฌ์šฉํ•˜๊ธฐ

์œ„์—์„œ ๊ตฌํ˜„ํ•œ permission์ฒ˜๋Ÿผ ์ œํ•œ์ ์ธ ์ƒํ™ฉ์—์„œ๋งŒ CRUD๋“ฑ์˜ ๊ธฐ๋Šฅ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค์—ˆ๋‹ค๋ฉด,

๋‹ค๋ฅธ ์ƒํ™ฉ์—์„œ CRUD๋ฅผ ์š”์ฒญํ–ˆ์„ ๋•Œ ์–ด๋–ค ์‘๋‹ต์ด ๋‚˜์˜ค๋Š”์ง€ ์žฅ๊ณ  ์‚ฌ์ดํŠธ๋งŒ์œผ๋กœ๋Š” ์•Œ๊ธฐ๊ฐ€ ํž˜๋“ค๋‹ค.

 

์ด๋Ÿฐ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์ดํŠธ์— ํŠน์ • ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‘๋‹ต์„ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ๋Š” Postman ํ”Œ๋žซํผ์„ ์‚ฌ์šฉํ•ด๋ณธ๋‹ค.

 

์ง์ ‘ ํ˜•ํƒœ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ์œผ๋ฏ€๋กœ raw ์˜ต์…˜์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

PUT์„ ์‚ฌ์šฉํ•ด question_id = 12 ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด์— update ์š”์ฒญ์„ ๋ณด๋‚ด๋ณด๋ฉด..

 

403 Forbidden ์—๋Ÿฌ๋ฅผ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ๋‹ค!

์—ญ์‹œ ๋กœ๊ทธ์ธ์ด ๋˜์–ด์žˆ์ง€ ์•Š์•„ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜ํƒ€๋‚œ๋‹ค.

 

๊ทธ๋Ÿฌ๋ฉด Postman์—์„œ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๋„˜๊ธฐ๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

 

์‚ฌ์ดํŠธ์˜ ๊ฐœ๋ฐœ์ž๋„๊ตฌ>Applicationํƒญ>Cookies๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด ํ•„์š”ํ•œ name๊ณผ value๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

sessionid๊ฐ€ ๋กœ๊ทธ์ธ์ •๋ณด, csrftoken๋„ ๋‚˜์˜จ๋‹ค.

์ด๊ฑธ Postman์— ๋„ฃ์–ด ์žฌ์‹œ๋„ํ•ด๋ณด์ž.

 

csrftoken์€ ์œ„์ฒ˜๋Ÿผ ๋‘๋ฒˆ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

 

'TIL' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[TIL]KDT_20230501  (0) 2023.05.01
[TIL]KDT_20230428  (0) 2023.04.28
[TIL]KDT_20230426  (0) 2023.04.26
[TIL]KDT_20230425  (0) 2023.04.25
[TIL]KDT_20230424  (0) 2023.04.24