【Django】用户登录与注销、判断用户是否登录

我们可以可以使用Django的认证功能来管理用户的登录与注销

1.login()登录

login()函数需要request和user这两个参数,它会把user的信息写入到 session,并且把sessionid存到cookie中

users.views.py(注册,注册完之后即登录)

from django.contrib.auth import login  # 导入登录
from django import http

# 注册,注册完之后即登录
class RegisterView(View):
    def post(self,request):
	# 注册用户
		try:
		    user = User.objects.create_user(username="laowang",password="123456",mobile="10086")
		except Exception as e:
		    return http.JsonResponse({
    
    'code': 400, 'errmsg': '注册失败!'})
		
		# 如果注册成功,让用户保持登录
		login(request, user)
		
		# 一般我们会自己决定登录有效期,比如说14天
		response = http.JsonResponse({
    
    "code":0,"errmsg":"注册成功"})
        response.set_cookie("username",user.username,max_age=3600*24*14)
        return response 

users.views.py(普通登录)

# 导入Django的认证模块
from django.contrib.auth import login, authenticate
from django import http

class LoginView(View):
    def post(self, request):
    	 # 校验用户名和密码是否正确
    	 user = authenticate(request,username=username,password=password)
         if user is None:
            return http.JsonResponse({
    
    "code":400,"errmsg":"用户或密码错误"})
	   	 login(request, user)  # 校验完正确性之后登录
	   	 # 判断用户是否勾选记住登录
	   	  if remembered != True:
	           # 如果没有记住,session在关闭浏览器后立刻失效
	           request.session.set_expiry(0)
	      else:
	           # 如果记住,设置session有效期为14天(默认)
	          request.session.set_expiry(None)
	      response = http.JsonResponse({
    
    'code': 0, 'errmsg': 'ok'})
	      # 在cookie中设置用户名,用作前端页面展示
	      response.set_cookie(key='username', value=user.username, max_age=3600 * 24 * 14)
	      return response

上面的代码使用到了一个authenticate()方法来进行校验,该方法只会根据username字段去过滤查找用户,所以我们需要重写该方法完成自定义校验功能

users/utils.py

from django.contrib.auth.backends import ModelBackend
from django.db.models import Q # 借助Q对象,实现用户名、手机号或email都可以登录
from .models import User

# 继承Django默认的认证后端
class UsernameMobileAuthBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            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表示认证失败

        # 若找到了,再校验密码
        if user.check_password(password):
            return user

在配置文件声明使用自定义的认证后端

# 指定自定义的用户认证后端:
AUTHENTICATION_BACKENDS = [
    'apps.users.utils.UsernameMobileAuthBackend'
]

2.logout()注销

users.views.py

from django.contrib.auth import logout

class LogoutView(View):
	# 前端用DELETE方式发起请求
    def delete(self, request):
        # logout(),会清理 session
        logout(request)
        response = http.JsonResponse({
    
    'code':0, 'errmsg':'ok'})
        # 手动删除返回的cookie
        response.delete_cookie('username')
        return response

3.判断用户是否登录

我们可以使用Django提供的 LoginRequiredMixin 判断用户是否登录,但是,

系统自带的LoginRequiredMixin 在用户未登录的情况下,返回的是 重定向到登录 的操作,不过我们这里是前后端分离开发,只需要返回个json数据给前端即可,所以我们需要继承重写handle_no_permission()方法

meiduo_mall.utils.views.py

from django.contrib.auth.mixins import LoginRequiredMixin
from django import http

# 继承LoginRequiredMixin类,重写handle_no_permission()方法
class LoginRequiredJSONMixin(LoginRequiredMixin):
	# 若用户未登录,直接返回json给前端
    def handle_no_permission(self):
        return http.JsonResponse({
    
    'code': 400, 'errmsg': '用户未登录'})

users.views.py

from meiduo_mall.utils.views import LoginRequiredJSONMixin

class UserInfoView(LoginRequiredJSONMixin, View):
    def get(self, request):
        return http.JsonResponse({
    
    
            "code":0,
            "errmsg":"ok",
            "info_data":{
    
    
                "username":request.user.username,
                "mobile":request.user.mobile,
                "email":request.user.email,
            }
        })
补充说明:

如果不继承LoginRequiredMixin,也可以自己根据request.user判断用户是否登录

1.request.user就是当前已经登陆的用户对象

2.如果用户未登陆,则request.user是一个AnonymousUser对象(匿名用户)

3.request.user.is_authenticated 可以判断是否已经登录,返回值为True说明已经登录,False则未登录

猜你喜欢

转载自blog.csdn.net/qq_39147299/article/details/108405650