"장고 OAuth2.0 제공"의 두 판 사이의 차이

Pywiki
둘러보기로 가기 검색하러 가기
(새 문서: == 개요 == django-oauth-toolkit을 통해 OAuth2.0 로그인을 제공한다. 이미 로그인 뷰 등 기본적인 서비스는 구현된 상태라 가정한다. {| class="wikitab...)
 
 
(다른 사용자 한 명의 중간 판 3개는 보이지 않습니다)
1번째 줄: 1번째 줄:
 
== 개요 ==
 
== 개요 ==
django-oauth-toolkit을 통해 OAuth2.0 로그인을 제공한다.
+
django-oauth-toolkit을 통해 OAuth2.0 로그인을 제공한다. 공식 문서(https://django-oauth-toolkit.readthedocs.io/en/latest/)
 +
 
 +
애시당초 공급을 목표로 하는 라이브러리.
  
 
이미 로그인 뷰 등 기본적인 서비스는 구현된 상태라 가정한다.
 
이미 로그인 뷰 등 기본적인 서비스는 구현된 상태라 가정한다.
36번째 줄: 38번째 줄:
 
|보통 custom_account를 구성하기에, auth 따위는 이쪽으로 넘기는 것도 좋을듯.
 
|보통 custom_account를 구성하기에, auth 따위는 이쪽으로 넘기는 것도 좋을듯.
 
|-
 
|-
 +
|form 제작
 +
|<syntaxhighlight lang="python3">
 +
from oauth2_provider.models import get_application_model
 +
Application = get_application_model()
 +
class ClientRegisterForm(forms.ModelForm):
 +
    class Meta:
 +
        model = Application
 +
        fields = ['name', 'redirect_uris']
 +
        widgets = {
 +
            'redirect_uris': forms.Textarea(attrs={'rows': 3}),
 +
        }
 +
</syntaxhighlight>
 +
|
 +
|}
 +
 +
== 클라이언트 페이지 만들기. ==
 +
{| class="wikitable"
 +
!과정
 +
!설명
 +
!비고
 +
|-
 +
|url 설정.
 +
|<syntaxhighlight lang="python3">
 +
# OAuth2.0 관련.
 +
path('OAuth2.0/client_list', views.OAuth_client_list, name='OAuth_client_list'),
 +
path('OAuth2.0/detail/<int:pk>', views.OAuth_client_edit, name='OAuth_client_edit'),
 +
path('OAuth2.0/register', views.OAuth_register_client, name='OAuth_register_client'),
 +
path('OAuth2.0/delete/<int:pk>', views.OAuth_delete_client, name='OAuth_delete_client'),
 +
</syntaxhighlight>
 +
|예시. 각 사정에 맞게 설정.
 +
|-
 +
|view
 +
|<syntaxhighlight lang="python3">
 +
## OAuth2.0 제공 관련.
 +
from oauth2_provider.models import get_application_model
 +
from .forms import ClientRegisterForm
 +
Application = get_application_model()
 +
@login_required
 +
def OAuth_client_list(request):
 +
    '''사용자가 가진 어플리케이션의 설정 보기.(어플리케이션을 여러 개 만들 수 있게 해야 할듯)'''
 +
    apps = Application.objects.filter(user=request.user)
 +
    return render(request, 'custom_account/OAuth2/client_list.html', {'apps': apps})
 +
@login_required
 +
def OAuth_client_edit(request, pk):
 +
    '''어플리케이션 수정 페이지.'''
 +
    app = get_object_or_404(Application, pk=pk, user=request.user)
 +
 +
    if request.method == 'POST':
 +
        form = ClientRegisterForm(request.POST, instance=app)
 +
        if form.is_valid():
 +
            form.save()
 +
            return redirect('custom_account:OAuth_client_list')  # 수정 후 목록 페이지로 리다이렉트
 +
    else:
 +
        form = ClientRegisterForm(instance=app)
 +
 +
    return render(request, 'custom_account/OAuth2/register.html', {'form': form, 'is_edit':True})
 +
@login_required
 +
def OAuth_register_client(request):
 +
    '''어플리케이션 등록.'''
 +
    if request.method == 'POST':
 +
        form = ClientRegisterForm(request.POST)
 +
        if form.is_valid():
 +
            app = form.save(commit=False)
 +
            app.user = request.user
 +
            app.client_type = Application.CLIENT_CONFIDENTIAL
 +
            app.authorization_grant_type = Application.GRANT_AUTHORIZATION_CODE
 +
            app.save()
 +
            return redirect('custom_account:OAuth_client_list')
 +
    else:
 +
        form = ClientRegisterForm()
 +
    return render(request, 'custom_account/OAuth2/register.html', {'form': form})
 +
@login_required
 +
def OAuth_delete_client(request, pk):
 +
    '''어플리케이션 등록.'''
 +
    app = get_object_or_404(Application, pk=pk, user=request.user)
 +
    if app.user == request.user:
 +
        app.delete()
 +
        return redirect('custom_account:OAuth_client_list')
 +
    return render(request, 'custom_account/OAuth2/register.html', {'form': form})
 +
</syntaxhighlight>
 
|
 
|
 +
|-
 +
|list 탬플릿
 +
|<syntaxhighlight lang="python3">
 +
{% extends 'custom_account/section.html' %}
 +
 +
{% block content %}
 +
 +
 +
<div class="row row-cols-1 row-cols-md-2 g-4">
 +
  {% for app in apps %}
 +
    <div class="col">
 +
      <div class="card h-100 shadow-sm">
 +
        <div class="card-body">
 +
          <h5 class="card-title d-flex justify-content-between align-items-center">
 +
            {{ app.name }}
 +
            <span>
 +
            <a class="btn btn-outline-primary btn-sm" href="{% url 'custom_account:OAuth_client_edit' app.pk %}">정보 수정</a>
 +
            <a class="btn btn-outline-danger btn-sm" href="{% url 'custom_account:OAuth_delete_client' app.pk %}"
 +
            onclick="return confirm('정말로 삭제하시겠습니까? 되돌릴 수 없습니다.');">삭제</a>
 +
            </span>
 +
          </h5>
 +
          <p><strong>Client ID:</strong> {{ app.client_id }}</p>
 +
          <p><strong>Client Secret:</strong> {{ app.client_secret }}</p>
 +
          <p><strong>Redirect URIs:</strong></p>
 +
          <ul class="list-group list-group-flush">
 +
            {% for uri in app.redirect_uris.splitlines %}
 +
              <li class="list-group-item">{{ uri }}</li>
 +
            {% empty %}
 +
              <li class="list-group-item text-muted">(등록된 URI가 없습니다)</li>
 +
            {% endfor %}
 +
          </ul>
 +
        </div>
 +
      </div>
 +
    </div>
 +
  {% empty %}
 +
    <p class="text-muted">등록된 클라이언트 애플리케이션이 없습니다.</p>
 +
  {% endfor %}
 +
</div>
 +
 +
<a href="{% url 'custom_account:OAuth_register_client' %}" class="btn btn-outline-primary">
 +
  새 어플리케이션 등록.</a>
 +
 +
 +
 +
{% endblock %}
 +
</syntaxhighlight>
 
|
 
|
 +
|-
 +
|등록, 수정 탬플릿.
 +
|<syntaxhighlight lang="python3">
 +
{% extends 'custom_account/section.html' %}
 +
 +
{% block content %}
 +
 +
<h2>{{ is_edit|yesno:"클라이언트 수정,클라이언트 등록" }}</h2>
 +
<form method="post">
 +
  {% csrf_token %}
 +
  {{ form.as_p }}
 +
  <button type="submit" class="btn btn-primary">
 +
    {{ is_edit|yesno:"수정,등록" }}
 +
  </button>
 +
</form>
 +
 +
{% endblock %}
 +
</syntaxhighlight>
 
|
 
|
 
|}
 
|}
 +
비밀키 갱신 기능 구현 필요.
 
[[분류:장고 기능구현(중급)]]
 
[[분류:장고 기능구현(중급)]]

2025년 5월 14일 (수) 18:03 기준 최신판

1 개요[편집 | 원본 편집]

django-oauth-toolkit을 통해 OAuth2.0 로그인을 제공한다. 공식 문서(https://django-oauth-toolkit.readthedocs.io/en/latest/)

애시당초 공급을 목표로 하는 라이브러리.

이미 로그인 뷰 등 기본적인 서비스는 구현된 상태라 가정한다.

과정 설명 비고
설치 pip install django-oauth-toolkit
settings.py 설정
INSTALLED_APPS += [
    "oauth2_provider",
]
AUTHENTICATION_BACKENDS = [  # 보통 소셜로그인 등을 구현했다면 이미 있음.
    "django.contrib.auth.backends.ModelBackend",
]
OAUTH2_PROVIDER = {
    # 토큰 만료 시간(초)
    "ACCESS_TOKEN_EXPIRE_SECONDS": 36000,
}
url 등록
path("o/", include("oauth2_provider.urls", namespace="oauth2_provider")),
path("auth/", include("myapp.auth_urls")),  # 사용자 인증용
path("clients/", include("myapp.client_urls")),  # 클라이언트 등록용
기본적으로 제공되는 기능은 o/로 연결하고, 이외 필요한 기능은 기존 구성한 앱으로 넘기든가...
보통 custom_account를 구성하기에, auth 따위는 이쪽으로 넘기는 것도 좋을듯.
form 제작
from oauth2_provider.models import get_application_model
Application = get_application_model()
class ClientRegisterForm(forms.ModelForm):
    class Meta:
        model = Application
        fields = ['name', 'redirect_uris']
        widgets = {
            'redirect_uris': forms.Textarea(attrs={'rows': 3}),
        }

2 클라이언트 페이지 만들기.[편집 | 원본 편집]

과정 설명 비고
url 설정.
# OAuth2.0 관련.
path('OAuth2.0/client_list', views.OAuth_client_list, name='OAuth_client_list'),
path('OAuth2.0/detail/<int:pk>', views.OAuth_client_edit, name='OAuth_client_edit'),
path('OAuth2.0/register', views.OAuth_register_client, name='OAuth_register_client'),
path('OAuth2.0/delete/<int:pk>', views.OAuth_delete_client, name='OAuth_delete_client'),
예시. 각 사정에 맞게 설정.
view
## OAuth2.0 제공 관련.
from oauth2_provider.models import get_application_model
from .forms import ClientRegisterForm
Application = get_application_model()
@login_required
def OAuth_client_list(request):
    '''사용자가 가진 어플리케이션의 설정 보기.(어플리케이션을 여러 개 만들 수 있게 해야 할듯)'''
    apps = Application.objects.filter(user=request.user)
    return render(request, 'custom_account/OAuth2/client_list.html', {'apps': apps})
@login_required
def OAuth_client_edit(request, pk):
    '''어플리케이션 수정 페이지.'''
    app = get_object_or_404(Application, pk=pk, user=request.user)

    if request.method == 'POST':
        form = ClientRegisterForm(request.POST, instance=app)
        if form.is_valid():
            form.save()
            return redirect('custom_account:OAuth_client_list')  # 수정 후 목록 페이지로 리다이렉트
    else:
        form = ClientRegisterForm(instance=app)

    return render(request, 'custom_account/OAuth2/register.html', {'form': form, 'is_edit':True})
@login_required
def OAuth_register_client(request):
    '''어플리케이션 등록.'''
    if request.method == 'POST':
        form = ClientRegisterForm(request.POST)
        if form.is_valid():
            app = form.save(commit=False)
            app.user = request.user
            app.client_type = Application.CLIENT_CONFIDENTIAL
            app.authorization_grant_type = Application.GRANT_AUTHORIZATION_CODE
            app.save()
            return redirect('custom_account:OAuth_client_list')
    else:
        form = ClientRegisterForm()
    return render(request, 'custom_account/OAuth2/register.html', {'form': form})
@login_required
def OAuth_delete_client(request, pk):
    '''어플리케이션 등록.'''
    app = get_object_or_404(Application, pk=pk, user=request.user)
    if app.user == request.user:
        app.delete()
        return redirect('custom_account:OAuth_client_list')
    return render(request, 'custom_account/OAuth2/register.html', {'form': form})
list 탬플릿
{% extends 'custom_account/section.html' %}

{% block content %}


<div class="row row-cols-1 row-cols-md-2 g-4">
  {% for app in apps %}
    <div class="col">
      <div class="card h-100 shadow-sm">
        <div class="card-body">
          <h5 class="card-title d-flex justify-content-between align-items-center">
            {{ app.name }}
            <span>
            <a class="btn btn-outline-primary btn-sm" href="{% url 'custom_account:OAuth_client_edit' app.pk %}">정보 수정</a>
            <a class="btn btn-outline-danger btn-sm" href="{% url 'custom_account:OAuth_delete_client' app.pk %}"
            onclick="return confirm('정말로 삭제하시겠습니까? 되돌릴 수 없습니다.');">삭제</a>
            </span>
          </h5>
          <p><strong>Client ID:</strong> {{ app.client_id }}</p>
          <p><strong>Client Secret:</strong> {{ app.client_secret }}</p>
          <p><strong>Redirect URIs:</strong></p>
          <ul class="list-group list-group-flush">
            {% for uri in app.redirect_uris.splitlines %}
              <li class="list-group-item">{{ uri }}</li>
            {% empty %}
              <li class="list-group-item text-muted">(등록된 URI가 없습니다)</li>
            {% endfor %}
          </ul>
        </div>
      </div>
    </div>
  {% empty %}
    <p class="text-muted">등록된 클라이언트 애플리케이션이 없습니다.</p>
  {% endfor %}
</div>

<a href="{% url 'custom_account:OAuth_register_client' %}" class="btn btn-outline-primary">
   어플리케이션 등록.</a>



{% endblock %}
등록, 수정 탬플릿.
{% extends 'custom_account/section.html' %}

{% block content %}

<h2>{{ is_edit|yesno:"클라이언트 수정,클라이언트 등록" }}</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit" class="btn btn-primary">
    {{ is_edit|yesno:"수정,등록" }}
  </button>
</form>

{% endblock %}

비밀키 갱신 기능 구현 필요.