Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- graphicdriver
- Xangle
- jaypark.dating
- 봉사활동
- CrossAngle
- machinelearning
- 나는리뷰어다
- 프로그래머스
- 결과를얻는법
- 인하멘토링
- intell
- 놀이동산의슈퍼컴퓨터를작동시켜라
- texttospeech
- 인하대학교
- 2019회고
- 로그남기기
- 심플소프트웨어
- 개발자회고
- 타코트론
- tacotron
- 한빛미디어
- 서구동구예비군훈련장
- 신영준
- 노트북덮개
- 프로그라피
- 우분투비트확인
- 인천남중
- 개발자를위한파이썬
- 쇠막대기
- 서버로그
Archives
- Today
- Total
jc.jang
16강 Permission 시스템을 통한 사용자 접근 제한하기 본문
주제
- Permission 시스템을 통한 사용자 접근 제한하기
노트
- 특정 User/Group에 Permission을 할당할 수 있다.
- admin 페이지에 각 User/Group 별로 Permission 할당 UI가 제공된다.
- 모델별로 퍼미션 지정이 가능하다.
- 디폴트 퍼미션 제공: 추가, 수정, 삭제
- admin 페이지에서 유저 클릭 후 권한 탭에서 사용자 권한을 확인, 부여할 수 있다.
- 사용자 권한을 부여하는 것과 별개로, 뷰에서 관련 로직을 따로 처리해줘야한다.
- 예를 들어, A라는 사용자에게 'can delete post' 권한을 준다고해서 post를 삭제할 수 있는건 아님
- 실제 상황에서 어떻게 쓰이는지 알아보자.
- 미션 - 로그인 여부를 먼저 검증하고, 로그인 유저가 GoldUser가 아닐 경우 등급 업그레이드 안내 페이지 보여주기
- goldmembership_guide 페이지 만들기
- blog.can_view_goldpage 권한 추가하기
- 뷰에 blog.can_view_goldpage 권한 제한하기
- 유저 혹은 그룹에 blog.can_view_goldpage 권한 부여하기
- 먼저 골드멤버가 아닐 경우, 골드 멤버십을 안내하는 페이지를 만든다.
- blog/urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
# ...
path('<int:pk>/', views.post_detail, name='post_detail'),
path('goldmembership_guide/', views.goldmembership_guide, name='goldmembership_guide')
]
- blog/views.py
def goldmembership_guide(request):
return render(request, 'blog/goldmembership_guide.html')
- blog/templates/blog/goldmembership_guide.html
{% extends "blog/layout.html" %}
{% block content %}
<h2>골드 멤버 가이드</h2>
골드 멤버만 접근할 수 있습니다.
골드 멤버가 되고 싶으면 댓글을 10번 이상 작성해야합니다.
{% endblock %}
- 위와 같이골드 멤버십을 안내하는 페이지를 작성한다.
- 그 다음으로 can_view_goldpage 권한을 추가한다.
from django.db import models
from django.shortcuts import reverse
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
permissions = [
('can_view_goldpage', 'Can View Goldpage')
]
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("blog:post_detail", kwargs={"pk": self.pk})
- Model의 Meta 클래스에는 상당히 많은 설정들이 가능하다.
- 그 중 permissions 필드를 재정의한다.
- 리스트안에 리스트 혹은 튜플로 데이터를 할당하고 첫번째 인자는 permisson_code, 두번째 인자는 human_readable_permission_name이다.
- 이렇게 작성하고 반드시 migrate를 해야한다. (실제로는 데이터베이스에 변경사항은 없음)
- 이제 우리가 만든 권한을 뷰에 적용한다.
- @permission_required(링크) 데코레이터를 활용하여 뷰를 다시 작성한다.
from django.urls import reverse_lazy
from django.shortcuts import render
from .models import Post
from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required
@login_required
@permission_required('blog.can_view_goldpage', login_url=reverse_lazy('blog:goldmembership_guide'))
def post_detail(request, pk):
post = Post.objects.get(pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
- 데코레이터를 두가지 사용했다.
- 먼저, 사용자가 로그인했는지 확인하기 위해 @login_required 데코레이터를 사용했고, 로그인한 사용자라면 blog.can_view_goldplage 권한이 있는지 확인하기 위해 @permission_required 데코레이터를 사용했다.
- 파라미터에 대한 자세한 설명은 위에 링크를 걸어 놓은 공식 문서에서 확인 가능하다.
- login_url은 권한이 없는 경우 이동할 페이지로 생각하면 된다.
- 마지막으로, 유저에게 권한을 부여하자.
python manage.py shell
>>> from django.contrib.auth import get_user_model
>>> user = get_user_model().objects.all().last()
>>> from django.contrib.contenttypes.models import ContentType
>>> from blog.models import Post
>>> content_type = ContentType.objects.get_for_model(Post)
>>> from django.contrib.auth.models import Permission
>>> permission = Permission.objects.get(codename='can_view_goldpage',content_type=content_type,)
>>> user.user_permissions.add(permission)
>>> user.has_perm('blog.can_view_goldpage')
False
>>> user = get_user_model().objects.all().last()
>>> user.has_perm('blog.can_view_goldpage')
True
- 이렇게 쉘에 진입하여 권한 부여가 가능하다. 혹은 admin 페이지의 권한 탭에서 UI를 이용하여 할 수도 있다.
- 그런데 코드에서 이상한 부분이 있다.
- user.user_permissions.add(permission)을 통해 권한을 부여하고 권한을 확인했더니 False가 반환되었다.
- 이것은 권한 캐싱(링크)때문이다.
- 사용자에 대해 처음 얻은 권한 정보를 캐싱하여 사용하므로, 권한을 추가한 후 바로 확인하는 경우 가장 쉬운 해결책은 데이터베이스에서 사용자를 다시 읽어오는 것이다.
질문
- medium이라는 온라인 출판 플랫폼을 이용하다 보면, '포스트를 무료로 확인할 수 있는 횟수를 모두 사용하였습니다.'와 같은 문구를 본 적이 있다. 이러한 기능을 구현하려면 어떻게 해야할까?
요약
- permission을 통해 사용자 권한을 부여할 수 있다.
- permission을 부여한 것과 별개로 view에서 처리하는 로직이 필요하다.
- permission caching을 사용하기 때문에 권한을 추가한 후 바로 확인하는 경우에는 사용자를 다시 읽어와야한다.
날짜
- 오전 2시, 20190919
'Django > Django - 인증편' 카테고리의 다른 글
18강 SignupForm에 Meta.model 적용하기 (0) | 2019.09.09 |
---|---|
17강 중복 로그인 막기 (0) | 2019.09.09 |
15강 User Admin 커스텀하기 (0) | 2019.09.08 |
14강 커스텀 User Model 만들기 (0) | 2019.09.05 |
13강 암호 재설정 구현하기 (0) | 2019.09.03 |
Comments