zoukankan      html  css  js  c++  java
  • AI-认证

     AI-认证

    做登录验证

    #models.py
    class Users(models.Model):
        user=models.CharField(max_length=32)
        pwd=models.CharField(max_length=32)
        type=((1,"VIP"),(2,"SVIP"),(3,"SSVIP"))
        user_type=models.IntegerField(choices=type)
    
    class Usertoken(models.Model):
        token=models.CharField(max_length=128)
        user=models.OneToOneField("Users")

    #url.py
    url(r'^login/',views.LoginView.as_view()),
    #views.py

    from
    rest_framework.views import APIView from rbac.models import * from rest_framework.response import Response #使用postman模拟发送post请求,后端取到request.data中的数据,进行和数据库中的 #数据做校验,如果正确返回response这个字典,里边状态码为1000。并且再数据库创建token值,token值的创建,
      如果token已经存在,则为了节省内存,使用update_or_create覆盖掉之前token,如果不存在的话,创建token值即可!; #如果校验错误,返回错误的状态码,使用try
    -except; #当异常操作时,返回异常错误; class LoginView(APIView): """ 1000:成功 1001:用户名或者密码错误 1002:异常错误 """ def post(self, request): response = {"code": 1000, "msg": None, "user": None} try: print(request.data) user = request.data.get("user") pwd = request.data.get("pwd") user = Users.objects.filter(user=user, pwd=pwd).first() import uuid random_str = uuid.uuid4() #uuid用来生成随机的token字符串 if user: Usertoken.objects.update_or_create(user=user, defaults={"token": random_str}) response["user"] = user.user response["token"] = random_str else: response["code"] = 1001 response["msg"] = "用户名或者密码错误" except Exception as e: response["code"] = 1002 response["msg"] = str(e) return Response(response)

    postman效果:

    提前将密码和用户名存在数据库中

    发送:    
    {
            "user":"alex",
            "pwd": 123
        }
    返回:
    {
        "code": 1000,
        "msg": null,
        "user": "alex",
        "token": "14339f3b-173b-4682-a361-cc699d84fa15"
    }

     数据库中效果:

    做数据验证

    使用token取数据库中的数据,只有登录了的用户才可以拿取数据

    #url.py
        url(r'^course/', views.Courseview.as_view()),
        url(r'^login/', views.LoginView.as_view()),
    #views.py
    #一个视图类,先不走get,post方法,先走他的组件,比如parser_classes、authentication_classes等组件,
    在使用auth认证时,校验合格之后才会走get方法,简而言之,只有登录了的用户(数据库存在用户信息的用户)才可以拿着token访问
    数据,也就是走get和post请求!
    from
    rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationFailed class UserAuth(BaseAuthentication): def authenticate(self,request): #这个函数用来校验GET中的token和数据库中的token是否一样! token=request.query_params.get("token") #query_params里封装了self._request.GET
                                 #从request中拿到token值
    usertoken=Usertoken.objects.filter(token=token).first() #将GET方法中拿到的token和数据库中的做校验 if usertoken: return usertoken.user,usertoken.token #返回认证成功的用户的,用户名和用户token else: raise AuthenticationFailed("认证失败!") #认证失败,使用AuthentitionFailed返回报错信息 class Courseview(APIView): authentication_classes = [UserAuth] #传入认证组件,和序列化组件只差这个东西 def get(self,request): course_list=Course.objects.all() cs=CourseSerializer(course_list,many=True) print(cs.data) return Response(cs.data) #我的序列化接口 def post(self,request): print(request.data) cs=CourseSerializer(data=request.data) if cs.is_valid(): Course.objects.create(**request.data) return Response(cs.data) else: return Response(cs.errors)

    使用postmanGET:

    a.访问:http://127.0.0.1:8004/course/
    返回:报错

      {
      "detail": "认证失败!"
      }

    
    b.访问:http://127.0.0.1:8004/course/?token=74d1679d-1a2d-47b1-852b-6f2d74a13cc1
    (token是在数据库中取到的)
    返回:
    [
        {
            "title": "羊肚儿",
            "desc": "煮10秒钟,贼香"
        },
        {
            "title": "宽粉",
            "desc": "两盘儿,配上我妈给我调的料"
        },
        {
            "title": "fei",
            "desc": "mybro"
        },
        {
            "title": "fei",
            "desc": "mybro"
        }
    ]

    认证源码解析

     其实也可以在局部给配置两个认证器,要想执行第二个认证,第一个认证执行完必须返回None,一般使用一个认证。认证配置的地方也有三个,局部、全局、默认,当配置到全局settings中时,访问所有的数据时都会自动做认证,没有登录,也就是拿不到token时,都无法访问数据。

    class BookView(APIView):
    
                 authentication_classes = [UserAuth,UserAuth2]
      
            self.dispatch:
                # 2. 认证,权限,频率
                self.initial(request, *args, **kwargs)
                    # 4. 实现认证
                    self.perform_authentication(request)
                            request.user
                                    self._authenticate()
                                            # 循环认证类的所有对象
                                            #[UserAuth(),UserAuth2()]
                                            for authenticator in self.authenticators: 
                                                try:
                                                    # 执行认证类的authenticate方法
                                                    # 1. 如果authenticate方法抛出异常,self._not_authenticated()执行
                                                    # 2. 有返回值,必须是元组:(request.user, request.auth)
                                                    # 3. 返回None,我不管,下一个认证来处理。使用返回None,可以做多个认证,最后一个认证返回值就行。
                                                    user_auth_tuple = authenticator.authenticate(self)
                                                except exceptions.APIException:
                                                    self._not_authenticated()
                                                    raise
    
                                                if user_auth_tuple is not None:  #如果返回值,那么return会终止for循环,不走第二个认证,所以要默认返回None
                                                    self._authenticator = authenticator
                                                    self.user, self.auth = user_auth_tuple
                                                    return
  • 相关阅读:
    dom4j操作xml
    iOS 导航栏的那些事儿
    iOS--定时器(几种定时器的对比)
    iOS--优秀博客记录
    iOS--基础--文件操作
    iOS--动画--GitHub前50名的Objective-C动画相关库
    iOS--资料--类目Category收集
    iOS--资料--开源收集
    iOS--资料--开源项目及库
    ios--控件--自定义封装一个控件
  • 原文地址:https://www.cnblogs.com/djfboai/p/10079013.html
Copyright © 2011-2022 走看看