自定义用户传统身份认证的认证后端——实现多账号登录(退出登录)

1、在Django的子应用新建users/utils.py文件编辑如下
"""
自定义用户传统身份认证的认证后端
目的:实现用户名或手机号,多账号登陆
"""
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q # Q将多个条件,构建成互为"或"的条件
from .models import User

# 继承Django默认的认证后端
class UsernameMobileAuthBackend(ModelBackend):

    # 重写authenticate方法
    # 原因:默认的authenticate方法,只会根据username字段去过滤查找用户
    def authenticate(self, request, username=None, password=None, **kwargs):
        # 允许多账号登陆的情况下,前端传来的"username"有可能是用户名也有可能是手机号

        try:
            # 1、先按用户名查找
            user = User.objects.get(
                # username=="18588269037" or mobile=="18588269037"
                Q(username=username) |  Q(mobile=username) | Q(email=username)
            )
        except User.DoesNotExist as e:
            return None # 用户名找不到,返回None表示认证失败

        # 3、某一个找到了,再校验密码
        if user.check_password(password):
            return user
2、修改配置文件dev.py添加自定义认证后端
# 指定自定义的用户认证后端:
AUTHENTICATION_BACKENDS = [
    'apps.users.utils.UsernameMobileAuthBackend'
]
3、当我们进行传统登录接口设计的时候,就可以直接使用全局身份认证函数authenticate认证用户身份:
# 功能:验证用户名和密码 ---> 业务逻辑:通过用户名查找用户,再校验密码
# 参数:request请求对象,username用户名,password明文密码
# 返回值:用户名和密码校验成功返回用户对象,否则返回None
# 全局函数authenticate ---调用--->  ModelBackend.authenticate实例方法完成用户名和密码校验
user = authenticate(request=request, username=username, password=password)
if user is None:
	return JsonResponse({'code': 400, 'errmsg': '用户或密码输入有误'}, status=400)
4、登录视图接口代码:
# 传统登陆
class LoginView(View):

    def post(self, request):

        data = json.loads(request.body.decode())

        username = data.get('username')
        password = data.get('password')
        remembered = data.get('remembered', False)

        if not all([username, password, remembered]):
            return JsonResponse({'code': 400, 'errmsg': '缺少必传参数'})

        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            return JsonResponse({'code': 400, 'errmsg': '用户名格式错误'})
        if not re.match(r'^\w{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': '密码格式有误'}, status=400)

        # try:
        #     user = User.objects.get(username=username)
        # except User.DoesNotExist as e:
        #     return JsonResponse({'code': 400, 'errmsg': '找不到用户,username写错误 或 没注册'})
        # 
        # # 3.2、检查密码: User模型类对象继承自AbstractUser提供check_password函数用于校验明文密码
        # if not user.check_password(password):
        #     return JsonResponse({'code': 400, 'errmsg': '密码输入有误'}, status=400)
        
        user = authenticate(request=request, username=username, password=password)
        if user is None:
            return JsonResponse({'code': 400, 'errmsg': '用户或密码输入有误'}, status=400)
        
        # 状态保持
        login(request, user)

        # 设置session数据有效期
        if remembered != True:
            request.session.set_expiry(0)  # 有效期设置为0 —— 当用户关闭浏览器标签页则session失效
        else:
            request.session.set_expiry(None)  # 使用django默认的14天有效期

        response = JsonResponse({'code': 0, 'errmsg': 'OK'})
        # 设置cookies
        response.set_cookie(
            'username',
            user.username,
            max_age=3600*24*14

        )
        return response
5、 使用cookie展示首页用户名–功能实现

(后端)用户登录和注册的时候, 都需要把用户的信息写入到 cookie.

生成响应对象
response = http.JsonResponse({'code':0, 'errmsg':'ok'})

在响应对象中设置用户名信息.
# 将用户名写入到 cookie,有效期 14 天
response.set_cookie('username', user.username, max_age = 3600 * 24 * 14)
# 返回响应结果
return response

前端) 获取 cookie 信息, 进行页面展示
在 index.js 中:

下面涉及到前端代码, 我们不用添加.

data: {
    // 添加一个变量, 从 cookie 中获取用户信息后
    // 赋值给该变量
    username: '',
},
mounted(){
   // 获取 cookie 中的用户名
   // getCookie 这个方法位于 base.js 文件中.
   this.username = getCookie('username');
}

6、退出登录(清除状态保持)

django 给我们推出了一个 logout( ) 方法, 该方法正好和 login( ) 方法相反:

login() 函数, 可以把 user 信息, 写入到 session 中, 再把 sessionid 保存到 cookie 里.

logout() 函数则正好相反, 能够把 session 中的信息清除掉.
from django.contrib.auth import logout
# 用户退出登陆
class LogoutView(View):

    def delete(self, request):
        # 1、提取参数
        # 2、校验参数
        # 3、数据/业务处理
        # 通过request--->获取cookie中的sessionid--->根据sessionid删除redis中的用户数据
        logout(request)
        # 4、构建响应
        response = JsonResponse({'code': 0, 'errmsg': 'ok'})
        response.delete_cookie('username')
        return response
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值