登录功能课件详解:前后端

这篇博客详细介绍了两种登录实现方式:基于session和基于JWT的用户认证。在Vue前端,登录功能通过axios发送POST请求,验证用户信息并存储登录状态。Django后端则分别展示了如何处理登录请求,包括用户验证、生成session或token。此外,还讨论了如何支持多种登录方式,如自定义认证类来实现用户名和手机号的混合登录,并提供了退出登录的处理方法。
摘要由CSDN通过智能技术生成

<登录功能 1 session>

==vue前端==

// 点击登录触发
Login() {
  // 通过element自定义表单校验规则,校验用户输入的用户信息
  this.$refs["ruleForm"].validate(valid => {
    //如果通过校验开始登录
    if (valid) {
      // 发送ajax
      this.$axios.post("/users/login/", {
          user: this.LoginUser.name,
          pwd: this.LoginUser.pass,
        })
        .then(res => {
          console.log("@@登录的响应:", res)
          // 200代表登录成功,其他的均为失败
          if (res.data.code == 200) {
            // res.data为后端响应的json
            // 隐藏登录组件
            this.isLogin = false;
            // 登录信息存到本地缓存
            let user = JSON.stringify(res.data.user);
            //要求后台返回的数据
            //{
            //     "code":200, 
            //     'msg': "欢迎user",
            //     "user":{
            //       userName:"xxx",
            //     },
            //}
            // 前端存储用户信息,表示登录成功
            localStorage.setItem("user", user);
            // sessionStorage.setItem("")
            // 登录信息存到vuex,控制页面欢迎信息
            this.setUser(res.data.user);
            // 弹出通知框提示登录成功信息
            this.notifySucceed(res.data.msg);
          } else {//响应不是200
            // 清空输入框的校验状态
            this.$refs["ruleForm"].resetFields();
            // 弹出通知框提示登录失败信息
            this.notifyError(res.data.msg);
          }
        })
        .catch(err => {
          console.log(err)
          return Promise.reject(err);
        });
    } else {//未通过用户校验
      return false;
    }
  });
}

django/路由

# /users/login/
path("login/", Login.as_view()),

django/视图

from django.contrib.auth.hashers import check_password 
from django.contrib.auth import authenticate
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import *

class Login(APIView):
    def post(self, request):
        # 1. 获取前端数据
        # 前端发送post 数据{user:xxx, pwd:xxx} 
        username = request.data.get("user")
        password = request.data.get("pwd")

        #2. 验证用户
        # user = authenticate(username=username,password=password)
        try:
            user = User.objects.get(username=username)
        except:
            return Response({"code":204,"msg":"用户不存在!"})

        # 用户存在,验证密码
        if check_password(password, user.password):
            #密码正确
            #会话保持,django后端只需要简单设置session,返回的响应会带着sessionid---->Vue代理处理cookie存储
            request.session["username"] = username
            
            return Response({"code":200, "msg":"欢迎%s"%username, 'user':{"userName":username, 'uid':user.id}})
        # 验证未通过
        res = Response({"code":204, "msg":"用户名或密码不正确!"})
        return res

<登录功能 2 >携带 jwt token

自定义登录视图,使用pyjwt 自己生成 token, 此类方案支持所有的python框架

pip install jwt

生成token

import datetime
import jwt  #需要安装pip install pyjwt
from django.conf import settings

def generate_token(user):
    """
     :param user: 用户对象
     :return: 生成的token
    """
    #自己组织payload
    payload = {
        'user_id': user.id,
        'username': user.username,
        'exp': datetime.datetime.now() + datetime.timedelta(seconds=300)
    }
    # token 要自己生成: 第二部分的载荷,盐部分, 算法
    token = jwt.encode(payload=payload, key=settings.SECRET_KEY, algorithm='HS256')
    return token

jdango/登录视图

from django.contrib.auth import authenticate
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import *

class Login(APIView):
    def post(self, request):
    	#获取前端数据
        username = request.data.get('user')
        password = request.data.get('pwd')

        user = authenticate(username=username, password=password)

        if user:
            token = generate_token(user)
            return Response({
            	'code':200,
                'msg': '登录成功!',
                'token': token,
                'user': {
                    'userName': user.username,
                    'uid': user.id
                }
            })
        else:
            return Response({"code":204, 'msg': '用户名或密码错误'})

django/路由

urlpatterns = [
   path('login/', Login.as_view()),
]

Vue前端存储token

localStorage.setItem("token", res.data.token)
#后续的请求 携带token
let token = localStorage.getItem("token")

----------------------------------------------------------------------------------------------------------------------------

django方案二 携带token

自定义登录视图,使用 djangorestframework-jwt提供的 方法生成token,此类方案只能支持django框架

pip install djangorestframework-jwt

登录视图

from rest_framework_jwt.utils import jwt_payload_handler, jwt_encode_handler 
from django.contrib.auth import authenticate
from rest_framework.views import APIView
from rest_framework.response import Response
from user.models import *


class Login(APIView):
    def post(self, request):
        username = request.data.get('user')
        password = request.data.get('pwd')

        user = authenticate(username=username, password=password)

        if user:
            payload = jwt_payload_handler(user)
			token = jwt_encode_handler(payload)
            return Response({
            	"code":200,
                'msg': '登录成功!',
                'token': token,
                'user': {
                    'userName': user.username,
                    'uid': user.id
                }
            })
        else:
            return Response({"code":200, 'msg': '用户名或密码错误!'})

路由配置

urlpatterns = [
   path('login/', Login.as_view()),
]

---------------------------------------------------------------------------------------------------------------------------------

多方式登录

django内置的用户认证方式只支持 用户名和密码,而实际的项目开发中,登录方式往往不止一种

因此,需要重写用户认证类,指明新的 认证方式,添加手机号登录方式。

自定义身份认证类

utils/auth.py,在项目中创建一个utils目录,自定义认证类

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.hashers import check_password
from django.db.models import Q
from user.models import User


# 自定义 认证类,需要在 settings.py 中指明配置项
class AuthBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        """需要继承django内置的用户认证类,并重写认证方法,可以支持多种方式进行登录"""
        try:
            user = User.objects.get(Q(username=username) | Q(mobile=username))
        except Exception as e:
            return None
        # 校验密码: 先写 需要校验的密码, 后写 加密后的密码
        if check_password(password, user.password):
            return user
        else:
            return None

指明配置项

在配置文件中,指明认证类

# 指定用户认证引擎
AUTHENTICATION_BACKENDS = [
    'utils.auth.AuthBackend' , # 自己定义的认证类路径
]

--------------------------------------------------------------------------------------------------------------------------

退出登录

使用session会话保持的退出:

Vue前端

// 退出登录
logout() {
  // 不显示退出登录框
  this.visible = false;

  this.$axios.post("/users/logout/").then((res) => {
    console.log("@@退出登录的响应:", res);

    if (res.data.code == 200) {
      // 清空本地登录信息
      // localStorage.setItem("user", "");
      localStorage.removeItem("user");

      // 清空vuex登录信息
      this.setUser("");
      this.notifySucceed("成功退出登录");
    }else{
      console.log("退出请求失败")
    }
  }).catch(err=>{return Promise.reject(err)})
},

django后端

#/users/logout/
path("logout/", Logout.as_view()),

#视图接口
class Logout(APIView):
    def post(self, request):
        print("会话保持:", request.session.items())
        #前端Vue代理会处理sessionid的存储及Cookie信息的携带
        #删除会话
        if request.session.get("username"):
            del request.session["username"]
        print("再次查看session:", request.session.items())

        return Response({"code":200, "msg":"ok"})

使用jwt会话保持的退出:

只需要 删除 localStorage中存储的token即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值