欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

CRM --- 登录访问限制(基于中间件或login_required)

需求:

  • 除登录和注册之外,其他所用的页面都需要登录后才能访问,未登录用户访问其他页面都跳转到login页面。
  • 用户登录之后跳转到用户之前访问的页面。

一. 基于中间件的登录访问限制

验证中间件

AuthMiddleware.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
from django.urls import reverse


class AuthUserMiddleware(MiddlewareMixin):
    def process_request(self, request):
        # 白名单
        white_list = [reverse('login'), reverse('reg'), reverse('get_valid_code')]
        if request.path in white_list:
            return None
        
        # 记录用户之前访问的路由,登录成功之后跳转到该路由
        if not request.user.is_authenticated:
            next_path = request.path
            return redirect('%s?next=%s' % (reverse('login'), next_path))
View Code

setting.py中加入该中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # 中间件是从上往下走,由于该中间件中使用了request.user,该属性的赋值是AuthenticationMiddleware给的,所以一般自定义中间件都放在最后
    'app01.utils.AuthMiddleware.AuthUserMiddleware'
    
]
View Code

login视图函数

# 用户登录(基于ajax和用户认证组件)
def login(request):
    # 客户端提交的ajax请求
    if request.is_ajax():
        # 获取客户端上传上来的数据
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        code = request.POST.get('code')
        # 返回给客户端的数据字典
        response = {'user': None, 'error_msg': '', 'next': reverse('index')}
        # 验证码是否匹配,根据用户传上来的cookie,取到keep_str,然后进行匹配

        if code.upper() == request.session.get('keep_str').upper():
            if user and pwd:
                # 验证用户名
                user_obj = auth.authenticate(username=user, password=pwd)
                if user_obj:
                    auth.login(request, user_obj)
                    response['user'] = user
                else:
                    response['error_msg'] = '用户名或密码错误'
            else:
                response['error_msg'] = '用户名或密码不能为空'
        else:
            response['error_msg'] = '验证码错误'

        # 获取next的路由,加入字典返回json给ajax
        next_path = request.GET.get('next')
        if next_path:
            response['next'] = next_path
        # 使用JsonResponse返回一个json字符串数据
        return JsonResponse(response)
    else:
        return render(request, 'login.html')
View Code

前端ajax

    // 发送ajax请求
    $('#login-btn').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: {
                user: $('#user').val(),
                pwd: $('#password').val(),
                code: $('#code').val(),
                csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val()
            },
            success: function (response) {
                if (response.user) {
                    location.href = response.next
                } else {
                    $('.error-msg').text(response.error_msg).css('color', 'red')
                }
            }
        })
    });
View Code

未登录用户浏览器输入url

转到

登录成功后

 

二.基于login_required装饰器的登录访问限制

配置指定跳转的登录url地址,不指定默认是/acount/login/

setting.py

LOGIN_URL = '/login/'
View Code

视图中使用

views.py

from django.contrib.auth.decorators import login_required


# 相对哪个视图函数做限制就给哪个函数加该装饰器
@login_required
def index(request):
    return render(request, 'index.html')
View Code

 

三.总结

  • 说说应用场景吧,如果是公司后台操作系统肯定是除登录外的所有页面都需要登录后才能查看,这是使用中间件最为合适。
  • 如果是网站的个别页面需要登录后才能查看,这是使用login_required比较合适。

 

posted on 2018-11-06 10:36  Louiszj  阅读(234)  评论(0)    收藏  举报

导航