REST-framework快速構建API--認證

1、API使用流程

使用過API的同窗都知道,咱們不可能任意調用人家的API,由於經過API能夠獲取不少關鍵數據,並且這個API可能供多個部門或我的使用,因此必須是通過受權的用戶才能調用。python

API的使用過程通常是:數據庫

攜帶用戶名和密碼(或者是AK/SK)之類的信息進行登錄,得到一個受權的Token,後續經過此Token進行資源申請。流程圖以下:json

 

(A)用戶打開客戶端之後,客戶端要求用戶給予受權。

(B)用戶贊成給予客戶端受權,給用戶username和password。

(C)客戶端使用B中的信息得到的受權,向認證服務器申請令牌。

(D)認證服務器對客戶端進行認證之後,確認無誤,贊成發放令牌。

(E)客戶端使用令牌,向資源服務器申請獲取資源。

(F)資源服務器確認令牌無誤,贊成向客戶端開放資源。

 

2、REST-framework實現

一、用戶登錄url

urls文件api

  url(r'^login/$', views.LoginView.as_view(),name="login"),
 

二、models文件

新增用戶表和token表服務器

class User(models.Model):
    name=models.CharField(max_length=32)
    pwd=models.CharField(max_length=32)

class Token(models.Model):
    user=models.OneToOneField("User")
    token = models.CharField(max_length=128)

    def __str__(self):
        return self.token
 

三、serializer.py文件

用戶表api序列化app

class AuthorModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = "__all__"

 

 

四、views函數

一、實現user表APIdom

二、經過LoginView函數,實現用戶登錄,登錄成功後保存token到數據庫,並返回給用戶信息;登錄失敗則給用戶提示。函數

注意:post

用戶每次登錄時纔會進行認證,生成一次token,不須要每次調用api接口都生成新的token。測試

class AuthorModelView(viewsets.ModelViewSet):
    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers

def get_random_str(user):
    import hashlib,time
    ctime=str(time.time())

    md5=hashlib.md5(bytes(user,encoding="utf8"))
    md5.update(bytes(ctime,encoding="utf8"))

    return md5.hexdigest()

from .models import User

class LoginView(APIView):

    def post(self,request):

        name=request.data.get("name")
        pwd=request.data.get("pwd")
        user=User.objects.filter(name=name,pwd=pwd).first()
        res = {"state_code": 1000, "msg": None}
        if user:

            random_str=get_random_str(user.name)
            token=Token.objects.update_or_create(user=user,defaults={"token":random_str})
            res["token"]=random_str
        else:
            res["state_code"]=1001 #錯誤狀態碼
            res["msg"] = "用戶名或者密碼錯誤"

        import json
        return Response(json.dumps(res,ensure_ascii=False))

  

注意:在python2中須要修改

def get_random_str(user):
    import hashlib, time
    ctime = str(time.time())

    md5 = hashlib.md5(str(user))
    md5.update(ctime)

    return md5.hexdigest()

 

五、utils.py

將TokenAuth功能模塊單獨放入utils文件,便於擴展。

注意:

若是不繼承BaseAuthentication,則須要咱們本身寫authenticate_header函數。

def authenticate_header(self, request):
        pass

  繼承BASEAuthenticate後,則能夠省略,由於他自帶了。

from rest_framework import exceptions

from rest_framework.authentication import BaseAuthentication


from .models import *
class TokenAuth(BaseAuthentication):
    def authenticate(self,request):
        token = request.GET.get("token")
        token_obj = Token.objects.filter(token=token).first()
        if not token_obj:
            raise exceptions.AuthenticationFailed("驗證失敗123!")
        else:
            return token_obj.user.name,token_obj.token
 

 

3、應用

一、局部應用

當咱們只須要對局部資源進行認證時,能夠單獨設定authentication_classes變量,指定token功能模塊便可。

class AuthorModelView(viewsets.ModelViewSet):
    authentication_classes = [TokenAuth,]
    queryset = Author.objects.all()
    serializer_class = AuthorModelSerializers

 

測試:

 

加上Token後:

 

二、全局應用

 咱們在setttings文件裏面指定REST_FRAMEWORK變量便可。

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth",]
}

 

三、免token訪問

全局應用後,全部資源都須要攜帶token才能訪問,若是不但願通過認證的話,能夠以下設置:

在對應View函數裏面,設置變量authentication_classes爲空列表便可。

 

authentication_classes = []

 

相關文章
相關標籤/搜索