django_01项目 用户的登录退出以及判断用户是否登录
(忙着去学数学去了,内容可以有缺失不完整,两年前的随笔)
对于用户的账户密码登录主要逻辑
用户名登录
- 确定登录用户是已经注册的用户
- 登录过后实现用户的状态保持
1)请求方式
post
2)后端接收的表单参数:
-
- 用户名
- 密码
- 是否记住用户
3)响应结果
-
- 登录成功====>重定向首页
- 登录失败====>响应错误
class LoginView(View): """用户名登录""" def get(self, request): """ 提供登录界面 :param request: 请求对象 :return: 登录界面 """ return render(request, 'login.html') def post(self, request): """ 实现登录逻辑 :param request: 请求对象 :return: 登录结果 """ # 接受参数 username = request.POST.get('username') password = request.POST.get('password') remembered = request.POST.get('remembered') # 校验参数 # 判断参数是否齐全 if not all([username, password]): return http.HttpResponseForbidden('缺少必传参数') # 判断用户名是否是5-20个字符 if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username): return http.HttpResponseForbidden('请输入正确的用户名或手机号') # 判断密码是否是8-20个数字 if not re.match(r'^[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('密码最少8位,最长20位') # 认证登录用户 user = authenticate(username=username, password=password) if user is None: return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'}) # 实现状态保持 login(request, user) # 设置状态保持的周期 if remembered != 'on': # 没有记住用户:浏览器会话结束就过期 request.session.set_expiry(0) else: # 记住用户:None表示两周后过期 request.session.set_expiry(None) # 响应登录结果 return redirect(reverse('contents:index'))
用户名或者手机号登录
如果我们需要实现手机号或者用户名登录,就需要重写ModelBackend类中的authenticate()方法
在app中创建一个utils.py
from django.contrib.auth.backends import ModelBackend import re from .models import User def get_user_by_account(account): """ 根据account查询用户 :param account: 用户名或者手机号 :return: user """ try: if re.match('^1[3-9]\d{9}$', account): # 手机号登录 user = User.objects.get(mobile=account) else: # 用户名登录 user = User.objects.get(username=account) except User.DoesNotExist: return None else: return user class UsernameMobileAuthBackend(ModelBackend): """自定义用户认证后端""" def authenticate(self, request, username=None, password=None, **kwargs): """ 重写认证方法,实现多账号登录 :param request: 请求对象 :param username: 用户名 :param password: 密码 :param kwargs: 其他参数 :return: user """ # 根据传入的username获取user对象。username可以是手机号也可以是账号 user = get_user_by_account(username) # 校验user是否存在并校验密码是否正确 if user and user.check_password(password): return user
在global_setting.py中指定了用户认证后端
我们需要在配置文件中重新指定用户认证后端
# 指定自定义的用户认证后端 AUTHENTICATION_BACKENDS = ['users.utils.UsernameMobileAuthBackend']
退出登录
django认证系统提供了login()方法来实现登录用户的状态保持,原理是将通过认证的用户的唯一标识信息,写入到当前session会话中。django也提供了logout()方法用来实现清理保持登录的session
位置:jango.contrib.auth.__init__.py
class LogoutView(View): """退出登录""" def get(self, request): """实现退出登录逻辑""" # 清理session logout(request) # 退出登录,重定向到登录页 response = redirect(reverse('contents:index')) # 退出登录时清除cookie中的username response.delete_cookie('username') return response
判断用户是否登录
is_authenticate判断用户是否登录
django认证系统提供了request.user.is_authenticated()方法判断用户是否登录,返回值为布尔值
class UserInfoView(View): """用户中心""" def get(self, request): """提供个人信息界面""" if request.user.is_authenticated(): return render(request, 'user_center_info.html') else: return redirect(reverse('users:login'))
LoginRequiredMixin
在我们需要验证用户登录的类中添加一个LoginRequiredMixin参数,导包路径是
from django.contrib.auth.mixins import LoginRequiredMixin。要在第一个参数的位置
如果用户是未登录的状态会重定向到global_settings中的LOGIN_URL,可以在配置文件中重写它的值。并且未登录重定向会在url最后面添加redirect_field_name,默认值为next,可以在配置文件中重写值。后面可以通过next实现登录之后跳转到未登录想要进入的页面
login_required装饰器判断用户是否登录