Django 阻止直接 url 访问

时间:2021-03-17 15:37:51

标签: django django-models django-views django-templates

假设我有

.decs

def unwelcome_user(unwelcome_roles=[]):
        def decorator(view_func):
            def wrapper_func(request, *args, **kwargs):
                if request.user.is_authenticated:
                    for group in request.user.groups.all():
                        if group.name in unwelcome_roles:
                            return redirect('main:unwelcome-user-type', 
                                             user_type=group.name)
                        else:
                            return view_func(request, *args, **kwargs)
                else:
                    return view_func(request, *args, **kwargs)
            return wrapper_func
        return decorator

.urls

urlpatterns = [
    path('error-unwelcome/<str:user_type>', views.unwelcome_user, name='success')
]

.views

@unwelcome_user(unwelcome_roles=['xyz'])
def success(request) 
    return render(request, 'success_page.html', {})

def unwelcome_user(request, user_type):
return render(request, 'errors/unwelcome_user.html', {})

我可以通过在浏览器中输入类似 mysite.com/error-unwelcome/xyz 的内容直接访问 unwelcome_user 视图,即使不经过应该导致显示该页面的后续过程。 我该如何预防?

4 个答案:

答案 0 :(得分:1)

我还是 Django 的新手,所以我无法尝试给出的 cookie/sessions 答案(我仍然需要学习 session)。与此同时,这是我正在使用的:

def get_referer(request):
    referer = request.META.get('HTTP_REFERER')
    if not referer:
        return None
    return referer

然后在任何视图中

def my_view(request):
    if not get_referer(request):
        raise Http404
    return render(request, 'sample.html', {})

这里我假设如果没有引用者,则表示在浏览器中输入 URL 的人。

答案 1 :(得分:0)

如果页面是供用户导航的页面链的一部分,则在从一个页面移动到下一个页面时,您需要传递一些状态。您可以使用 cookie 并在视图中检查 cookie 的值,也可以传递 GET 查询参数:

def success(request):
  token = request.GET.get('token', None)

  if token is None or not Token.objects.filter(value=token).exists():
    return redirect(...) # previous step or beginning

  return render(...) # page

以前的页面应该创建此令牌。然后在 URL 中传递它:

/success/?token=<token>

答案 2 :(得分:0)

试试这个

如果your_subsequent_process()返回True,process_page只会渲染success.html,否则会渲染process.html。

def proces_page(request):
    """Your Process View"""
    
    if your_subsequent_process():
        return render(request, 'success.html', {})

    return render(request, 'proces.html', {})

答案 3 :(得分:0)

您可以尝试使用 sessions [Django docs]。如果您要将用户重定向到页面,则在重定向之前只需向会话添加一个变量,指示他们可以访问视图。

所以就在重定向之前:

request.session['is_unwelcome'] = True
return redirect('main:unwelcome-user-type', user_type=group.name)

在视图中,您只需检查会话中是否存在变量:

def unwelcome_user(request, user_type):
    if 'is_unwelcome' not in request.session:
        # Redirect or raise Http 404?
        # return redirect('somewhere')
        # raise Http404()
    del request.session['is_unwelcome']
    return render(request, 'errors/unwelcome_user.html', {})