使用【Django】的Auth功能和Message框架来为每个用户设置访问权限的方法
总结
-
- Djangoにて、ユーザー(グループ)ごとにページへのアクセス制限が設定し、アクセス権がない場合はフラッシュメッセージ(アラートみたいなポップアップ)を表示する実装を行いました。
デフォルトで実装されているauth機能と、メッセージフレームワークを利用します。
本記事ではその実装方法を記載します。
假设条件
- ディレクトリ構造は以下の通りです(関係ないものは省略)。
app
├── app
│ ├── settings.py
│ └── etc...
├── home
│ ├── views.py
│ ├── urls.py
│ ├── etc...
│ └── templates/pages
│ ├── base.html
│ └── home.html
└── sample
│ ├── views.py
│ ├── urls.py
│ └── templates/sample
│ ├── base.html
│ └── sample.html
└── sample2 etc...
home.htmlには、sampleやsample2のボタンがあり、それをクリックするとそれぞれのhtmlに飛べる状態になっています。今回のアクセス制限では、ボタンを押してもユーザーが該当のグループに属していない場合はホーム画面にリダイレクトされる実装を行います。
URLの直打ちでもルートにリダイレクトする設定になっています。
实施内容
1. 使用Auth功能创建Group并添加用户
2. 编辑settings.py文件
3. 编辑urls.py文件
4. 编辑views.py文件
5. 编辑HTML模板
以Auth功能创建组和添加用户。
-
- Djangoの管理者アカウントでログインします。
- Admin画面から「Group」を選択すると、以下の画面に遷移されるので、任意の名前でグループを作成します。今回は「writers」とします。
- 次に、「Users」を選択して、任意のユーザー「hoge」を作成後、先ほどのグループに追加してあげます。
-
- 追加が終わったら、SAVEで保存します。
- これで、「writers」グループにユーザー「hoge」を追加することができました。
请编辑settings.py
- まず、’django.contrib.messages’や’django.contrib.messages.middleware.MessageMiddleware’が記載されていることを確認します(デフォルトで記載されているはず)。
INSTALLED_APPS = [
# 他のアプリケーション
'django.contrib.messages',
]
MIDDLEWARE = [
# 他のミドルウェア
'django.contrib.messages.middleware.MessageMiddleware'
]
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
- また、MESSAGE_STORAGEを追記します。これにより、メッセージはセッションストレージを使用して保存されるようになります。
编辑urls.py文件
from django.urls import path
from . import views
urlpatterns = [
path('', views.restricted_for_writers, name="sample"),
]
- ルートURLに対してviews.restricted_for_writersビューを関連付けます。restricted_for_writers関数は、次のviews.pyで定義します。
编辑views.py
from django.shortcuts import render
from django.shortcuts import redirect
from django.contrib import messages
# Loginユーザーのみアクセス可
@login_required
def index(request):
context = list_param(None)
return render(request, 'sample/sample.html', context)
# 該当のグループに属している場合のみアクセス可
def for_groups_only(*group_names):
def decorator(view_func):
def wrapper(request, *args, **kwargs):
user_groups = request.user.groups.values_list('name', flat=True)
if any(group_name in user_groups for group_name in group_names):
return view_func(request, *args, **kwargs)
else:
messages.warning(request, 'You do not have permission')
return redirect('/')
return wrapper
return decorator
# このビューは 'writers' または 'checkers' グループに属するユーザーのみがアクセスできる
@for_groups_only('writers', 'checkers')
def restricted_for_writers(request):
return render(request, 'sample/sample.html')
for_groups_onlyデコレータは、指定されたグループに属するユーザーのみがアクセスできるようにするためのデコレータです。
「writers」はDjango Authで作成したグループ名です。
编辑HTML模板
base.htmlテンプレート内には、メッセージフレームワークで表示されるメッセージを画面上部に表示するためのコードを記載します。
今回は以下のサイトよりコピーさせていただきました(Bootstrap4で表示)。
Djangoで通知メッセージを利用する(メッセージフレームワーク)
# 略
<body>
{% if messages %}
<ul class="messages_ul">
{% for message in messages %}
<li class="alert{% if message.tags %} alert-{{ message.tags }}{% endif %}" role="alert">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
# 略
完成了,現在開始驗證吧!
- 作成したユーザー「hoge」でログインしている状態で、アクセス権限のないURLへ飛ぶボタンをクリックすると、ホーム画面に戻って以下のメッセージがページ上部に表示されることを確認できました。
- 今回はwarningを指定していますが、他にも以下のような項目があります。
debug
info
success
warning
error
-
- ここのメッセージ内容や色は任意に変更ができます(詳しくはCSSなど)。Bootstrapの利用方法など、以下にも記載あるのでご参考ください。
【Django】通知メッセージを表示する方法(メッセージフレームワーク)
今回の実装方法では、URLの直打ちでも強制的にリダイレクトができます。実際に打ち込んでみると、ちゃんとホーム画面に遷移されました。
备考
- ちなみに、user_passes_testデコレータを使った実装方法もあります。ただし、この場合、リダイレクト先としてlogin_url=’/’と指定しているので、アクセス権限がない場合はルートURL(‘/’)に飛んでしまい、メッセージの表示ができませんでした。関数の中にif not…と記載してメッセージのコードを記載しても、リダイレクトが優先されてしまうようです。メッセージが不要な場合は以下の方が簡潔に実装できます。(このやり方で、メッセージも表示できる方法をご存知の方いましたらぜひ教えてください)
from django.shortcuts import render
from django.contrib.auth.decorators import user_passes_test
@user_passes_test(lambda u: u.groups.filter(name='writers').exists(), login_url='/')
def restricted_for_writers(request):
return render(request, 'sample/sample.html')
-
- 以上、いろいろやってみた結果、Auth機能とMessageフレームワークを使ったアクセス権限を設定する方法を実現できました。
-
- 今回の実装方法では、ユーザーによってはアクセスできないボタンがホーム画面に出る状態です。ユーザーごとにボタンの表示が変わる方がセキュリティ的には好ましいと思うので、別途その実装もしてみようと思います。
→23.05.18に投稿:【Django】Auth機能とカスタムテンプレートタグによってユーザーごとにアクセス可能なボタンを表示・非表示する方法
また、「アクセス権限がありません」というページを準備して、「ホーム画面に戻る」みたいなボタンを下部に設置するのも親切かもしれませんね。