zoukankan      html  css  js  c++  java
  • 登陆模块

    认证

    任何的项目都需要认证,用户输入了用户名和密码,验证通过,代表用户登录成功~~~

    那HTTP请求是无状态的,下次这个用户再请求,我们是不可能识别这个用户是否登录的~~

    所以我们就要有自己的方式来实现这个认证,也就是说~用户登录成功以后~~~我们给他们

    生成一个随机字符串~~以后这个用户再请求~~都要携带这个随机字符串~~

    我们就可以根据这个字符串进行判断这个用户是否登录~~~~

    那么大家想一个问题~~就是我们给登录的用户生成的随机字符串放在哪里呢~~~

    我们放哪里都可以~~目的是前端发送请求的时候带过来就可以了~~~

    以前的cookie,session是我们的一种解决方案~~我们讲认证的时候也用过token的这种解决方案~~

    1. 先创建redis连接池

    import redis
    
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379, decode_responses=True, max_connections=5)
    redis_pool.py

    2. 认证

    from app01.models import Account
    import redis
    from utils.redis_pool import pool
    
    
    
    # 基于redis的token认证
    conn = redis.Redis(connection_pool=pool)
    
    
    class LoginAuth(BaseAuthentication):
    
        def authenticate(self, request):
            # 认证通过 返回(user对象, token)
            # 不通过抛异常
            # 1. 拿到前端传过来的token
            # 2. 判断token是否存在
            # 3. 以及token是否过期
            if request.method == 'OPTIONS':
                return None
            token = request.META.get('HTTP_AUTHENTICATION', '')
            if not token:
                raise AuthenticationFailed('没有携带token')
            print(conn.exists(token), 1111111111111111)
            print(token)
            if not conn.exists(token):
                raise AuthenticationFailed('token过期')
            user_id = conn.get(token)
            user_obj = Account.objects.filter(id=user_id).first()
            return (user_obj, token)
    authentication.py

    TOKEN

    用户登录成功后,生成一个随机字符串token给前端返回~~~

    那么前端以后都携带这个token来访问~~这样我们只需要鉴别这个token~来做认证~~

    前端如果发送请求~把token放在请求头中~~我们看下我们的认证要怎么写~~

    在写认证之前,我们先把登录注册功能写了~~~

    1. 扩展用户表

    class Account(models.Model):
        username = models.CharField(max_length=32, verbose_name="用户姓名", unique=True)
        password = models.CharField(max_length=32, verbose_name="用户密码")
        # head_img = models.CharField(max_length=256, default='/static/frontend/head_portrait/logo@2x.png',
        #                             verbose_name="个人头像")
        token = models.UUIDField(null=True, blank=True)
    
        def __str__(self):
            return self.username
    
        class Meta:
            verbose_name = "11-用户表"
            db_table = verbose_name
            verbose_name_plural = verbose_name
    models.py

    2. 编写登录注册视图

    # 创建两个视图 一个注册的 一个登录的
    from django.shortcuts import render
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from utils.base_response import BaseResponse
    from .serializers import UserSerializer
    from course.models import Account
    import uuid
    # Create your views here.
    
    
    class UserView(APIView):
    
        # 注册用户
        def post(self, request):
            res = BaseResponse()
            ser_obj = UserSerializer(data=request.data)
            if ser_obj.is_valid():
                ser_obj.save()
                res.data = ser_obj.validated_data
            else:
                res.code = 1010
                res.data = ser_obj.errors
            return Response(res.dict)
    
    
    class LoginView(APIView):
    
        # 登录视图
        def post(self, request):
            res = BaseResponse()
            # 这里要获取我们的用户名密码 进行验证是否有这个用户
            # 而且我们这个密码前端一定是密文传过来 我们通过密文对比进行验证
            username = request.data.get("username", "")
            password = request.data.get("password", "")
            user_obj_queryset = Account.objects.filter(username=username, password=password)
            if not user_obj_queryset:
                res.code = 1003
                res.error = "用户名或密码错误"
            try:
                token = uuid.uuid4()
                user_obj_queryset.update(token=token)
                res.data = token
            except Exception as e:
                res.code = 1004
                res.error = "生成token失败"
            return Response(res.dict)
    views.py

    登录注册写完后, 开始写认证

    from rest_framework.authentication import BaseAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    from course.models import Account
    # django 提供的拿时间的接口 提供的是根据django配置的时区拿到的当前时间
    from django.utils.timezone import now
    
    
    class MyAuth(BaseAuthentication):
        def authenticate(self, request):
            if request.method == "OPTIONS":
                return None
            # print(request.META)
            token = request.META.get("HTTP_AUTHENTICATION", "")
            print(token)
            if not token:
                raise AuthenticationFailed({"code": 1021, "error": "缺少token"})
            user_obj = Account.objects.filter(token=token).first()
            if not user_obj:
                raise AuthenticationFailed({"code": 1020, "error": "无效的token"})
            else:
                old_time = user_obj.create_token_time
                if (now() - old_time).days > 7:
                    raise AuthenticationFailed({"code": 1020, "error": "无效的token"})
                return user_obj, token
    auth.py
    # 查看购物车是需要登录后才可以
    # 所有这是一个需要认证的接口
    class ShoppingCarView(APIView):
        authentication_classes = [MyAuth, ]
        # 展示购物车数据
        def get(self, request, *args, **kwargs):
            print(request.user)
            return Response("test")
    views.py 测试用的视图

    基于请求头的token认证就完成了~~~

  • 相关阅读:
    明年,我们依然年轻
    总有些东西会如台风一样的来
    ora00257错误处理方法
    ORACLE登录错误的解决方法
    C#中public new void add()的new在这里的意义
    Oracle Form Builder配置问题的一些总结
    作为程序员,你应该知道的职场晋升之路
    ORA01034错误的解决方法
    【转】JQUERY刷新页面
    【转】对C# 中堆栈,堆,值类型,引用类型的理解
  • 原文地址:https://www.cnblogs.com/peng104/p/10171282.html
Copyright © 2011-2022 走看看