rest-framework: an authentication component

A certification profile:

  Only authenticated users can access the specified url address, such as: information about courses, after sign-in required, not logged in, you can not see, at this time need to use certified components

Two topical use

models.py

class the User (models.Model): 
    name = models.CharField (MAX_LENGTH = 32 ) 
    pwd = models.CharField (MAX_LENGTH = 64 ) 
    user_type = models.IntegerField (choices = ((. 1, " super administrator " ), (2, " general administrator " ), (3, " . 2B user " )), default = 3 )
 # with the user table to do one association 
class Token (models.Model): 
    the user = models.OneToOneField (to = ' user ' ) 
    token = models.CharField (MAX_LENGTH = 64)

 New certification classes (verified by two parameters return)

rest_framework.authentication ROM Import BaseAuthentication
 from app01 Import Models
 from rest_framework.exceptions Import AuthenticationFailed
 from rest_framework.permissions Import BasePermission
 class MyAuth (BaseAuthentication):
     DEF the authenticate (Self, Request):
         # write some logic certified 
        # Print ( 'I am a certified class the method, as long as configured, will go I ') 
        token = request.GET.get ( ' token ' ) 
        token_obj = models.Token.objects.filter (token = token) .first ()
         IFtoken_obj:
             # has a value expressed logged 
            # the User objects currently logged token_obj.user 
            return token_obj.user, token_obj
         the else :
             # no value, representing not logged in, throw an exception 
            The raise AuthenticationFailed ( ' You are not logged ' )
MyPermision class (the BasePermission): 
Message = 'not a super user, can not see'
DEF has_permission (Self, Request, View):
IF request.user.user_type ==. 1:
return True
the else:
return False

 view layer:

from django.shortcuts import render,HttpResponse

# Create your views here.

from rest_framework.views import  APIView
from rest_framework.response import Response
from rest_framework.request import Request
from django.core.exceptions import ObjectDoesNotExist
from app01 import  models
from rest_framework.exceptions import AuthenticationFailed
import uuid
from rest_framework.authentication importBaseAuthentication 

from app01.MyAuths Import MyAuth, MyPermision 

# after the user must log in to get access to all books interfaces 
class Books (APIView):
     # can write multiple authentication class 
    # authentication_classes = [MyAuth,] 
    # only super users can access this interface 
    permission_classes = [MyPermision,]
     DEF GET (Self, Request):
         # request.user is the current logged-on user 
        Print (request.user.name)
         return the Response ( ' returns all books ' ) 

class Publish (APIView):
     # authentication_classes = [MyAuth, ] 
    permission_classes =[]
     DEF GET (Self, Request):
         Print (request.user.name)
         return the Response ( ' returns the information of all the press ' )
 class the Login (APIView): 
    authentication_classes = []
     DEF POST (Self, Request): 
        Response = { ' code ' : 100, ' MSG ' : ' successful login ' } 
        name = request.data.get ( ' name ' ) 
        pwd = request.data.get ( ' pwd ')
         The try :
             # GET has one and only one was not being given, the other Throws 
            the User = models.User.objects.filter (name = name, pwd = pwd) .get ()
             # successful login, you need to store data in the token table 
            # generate a unique idhg 
            token = uuid.uuid4 () 
            models.Token.objects.update_or_create (User = User, Defaults = { ' token ' :} token) 
            Response [ ' token ' ] = token
         the except of ObjectDoesNotExist AS E: 
            Response [ ' code ' ] = 101 
            Response [ 'MSG ' ] = ' user name or password is incorrect ' 
        the except Exception AS E: 
            Response [ ' code ' ] = 102
             # Response [' msg '] =' Unknown error ' 
            Response [ ' MSG ' ] = STR (E)
         return the Response ( response)

Annex: token verification database does not exist:

def get_token(id,salt='123'):
    import hashlib
    md=hashlib.md5()
    md.update(bytes(str(id),encoding='utf-8'))
    md.update(bytes(salt,encoding='utf-8'))

    return md.hexdigest()+'|'+str(id)

def check_token(token,salt='123'):
    ll=token.split('|')
    import hashlib
    md=hashlib.md5()
    md.update(bytes(ll[-1],encoding='utf-8'))
    md.update(bytes(salt,encoding='utf-8'))
    if ll[0]==md.hexdigest():
        return True
    else:
        return False

class TokenAuth():
    def authenticate(self, request):
        token = request.GET.get('token')
        success=check_token(token)
        if success:
            return
        else:
            raise AuthenticationFailed('认证失败')
    def authenticate_header(self,request):
        pass
class Login(APIView):
    def post(self,reuquest):
        back_msg={'status':1001,'msg':None}
        try:
            name=reuquest.data.get('name')
            pwd=reuquest.data.get('pwd')
            user=models.User.objects.filter(username=name,password=pwd).first()
            if user:
                token=get_token(user.pk)
                # models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
                back_msg['status']='1000'
                back_msg['msg']='登录成功'
                back_msg['token']=token
            else:
                back_msg['msg'] = '用户名或密码错误'
        except Exception as e:
            back_msg['msg']=str(e)
        return Response(back_msg)
from rest_framework.authentication import BaseAuthentication
class TokenAuth():
    def authenticate(self, request):
        token = request.GET.get('token')
        token_obj = models.UserToken.objects.filter(token=token).first()
        if token_obj:
            return
        else:
            raise AuthenticationFailed('认证失败')
    def authenticate_header(self,request):
        pass

class Course(APIView):
    authentication_classes = [TokenAuth, ]

    def get(self, request):
        return HttpResponse('get')

    def post(self, request):
        return HttpResponse('post')

Summary: topical use, only need to add in the view class:

authentication_classes = [TokenAuth, ]

Three global use:

REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}

Four source code analysis:

#Request对象的user方法
@property
def user(self):
the authentication classes provided to the request.
        if not hasattr(self, '_user'):
            with wrap_attributeerrors():
                self._authenticate()
        return self._user

def _authenticate(self):
        for authenticator in self.authenticators:
            try:
                user_auth_tuple = authenticator.authenticate(self)
            except exceptions.APIException:
                self._not_authenticated () 
                The raise 
            #Authentication is successful, you can return a tuple, but it must be the last class to return a verification 
            IF user_auth_tuple IS  not None: 
                self._authenticator = Authenticator 
                self.user, self.auth = user_auth_tuple
                 return 

        self._not_authenticated ()

self.authenticators

  def get_authenticators(self):
        return [auth() for auth in self.authentication_classes]

Class uses the authentication sequence: first with the view class verification class, then the class verification configuration settings in the last verification with the default class

Guess you like

Origin www.cnblogs.com/HUIWANG/p/11129664.html