欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

django restframework使用redis實(shí)現(xiàn)token認(rèn)證

 更新時(shí)間:2021年09月22日 09:28:23   作者:曲鳥  
本文主要介紹了django restframework使用redis實(shí)現(xiàn)token認(rèn)證,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

一、前言

restframework有自己很方便的一套認(rèn)證、權(quán)限體系:官方文檔(tokenauthentication)

官方文檔的token 是基于數(shù)據(jù)庫(kù)中的authtoken_token表來(lái)做的

在這里插入圖片描述

有時(shí)候在后續(xù)接口中需要使用的用戶信息過(guò)多時(shí),頻繁、高并發(fā)下的查詢數(shù)據(jù)庫(kù)會(huì)帶來(lái)比較大的性能消耗。這個(gè)時(shí)候我們就需要通過(guò)redis來(lái)做用戶認(rèn)證,并存儲(chǔ)一些用戶信息在其中。下面就為你講解如何基于redis來(lái)使用DRF做用戶認(rèn)證。

二、詳解

1. 前期準(zhǔn)備

1.1 安裝redis并啟動(dòng)

自行安裝!這個(gè)都裝不好后面的教程也不用看了!看了也理解不了!

1.2 安裝django-redis庫(kù)

pip install django-redis -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 配置redis

2.1 配置redis連接

settings.py輸入下面的代碼 (我的redis沒(méi)有設(shè)置密碼,所以配置代碼中無(wú)密碼相關(guān)配置)

# redis緩存配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "COMPRESSOR": "django_redis.compressors.zlib.ZlibCompressor",
            "IGNORE_EXCEPTIONS": True,
        }
    }
}

2.2 初始化redis連接

在項(xiàng)目初始化文件中(__init__.py)加入下面代碼進(jìn)行redis的初始化

在這里插入圖片描述

加入下列代碼

from django_redis import get_redis_connection
redis_connect = get_redis_connection()

3. 將token寫入redis

在之前的登錄接口是將token寫入數(shù)據(jù)庫(kù)的,現(xiàn)在需要重寫它讓其寫入redis

3.1 原來(lái)的登錄代碼

@api_view(['POST'])
def login(request):
    """
    登錄接口
    """
    user = authenticate(username=request.data['username'], password=request.data['password'])
    if user:
        Token.objects.filter(user_id=user.id).delete()
        token = Token.objects.create(user=user)
        _dict = {'id': user.id, 'username': user.username, 'first_name': user.first_name,
                 'last_name': user.last_name, 'email': user.email}        
        redis_connect.set(token.key, json.dumps(_dict), 259200)  # 存redis 259200秒=72個(gè)小時(shí)
        return Response(data={'status_code': 200, 'msg': '登錄成功!', 'token': token.key})
    return Response(data={'status_code': 403, 'msg': '密碼錯(cuò)誤!'})

3.2 重寫后的登錄代碼

@api_view(['POST'])
def login(request):
    """
    登錄接口
    """
    user = authenticate(username=request.data['username'], password=request.data['password'])
    if user:
        token = binascii.hexlify(os.urandom(20)).decode()  # 生成token 的方式
        _dict = {'id': user.id, 'username': user.username, 'first_name': user.first_name,
                 'last_name': user.last_name, 'email': user.email}
        redis_connect.set(token, json.dumps(_dict), 259200)  # 存redis 259200秒=72個(gè)小時(shí)
        return Response(data={'status_code': 200, 'msg': '登錄成功!', 'token': token})
    return Response(data={'status_code': 403, 'msg': '密碼錯(cuò)誤!'})

3.3 登錄后redis存儲(chǔ)的用戶記錄

在這里插入圖片描述

4. 重寫認(rèn)證token方法

4.1 源碼分析

我們可以全局搜索TokenAuthentication 找到【restframework】源碼中的Token認(rèn)證類

在這里插入圖片描述

這個(gè)類中我們只需要關(guān)注authenticate_credentials這個(gè)方法就可以了。

    def authenticate_credentials(self, key):
        model = self.get_model()
        try:
            token = model.objects.select_related('user').get(key=key)
        except model.DoesNotExist:
            raise exceptions.AuthenticationFailed(_('Invalid token.'))

        if not token.user.is_active:
            raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))

        return (token.user, token)

源碼首先通過(guò)接口請(qǐng)求的token (源碼中的key) 去數(shù)據(jù)庫(kù)中尋找是否有該對(duì)應(yīng)的記錄
如果有則認(rèn)證成功返回usertoken這兩個(gè)模型對(duì)象

如果沒(méi)有對(duì)應(yīng)的記錄,則拋出【invalid token】異常

        try:
            token = model.objects.select_related('user').get(key=key)
        except model.DoesNotExist:
            raise exceptions.AuthenticationFailed(_('Invalid token.'))

如果有對(duì)應(yīng)的記錄,但用戶是未激活的 (is_active=0) 則拋出【User inactive or deleted】異常

      if not token.user.is_active:
            raise exceptions.AuthenticationFailed(_('User inactive or deleted.'))

然后restframework會(huì)在視圖層的dispatch方法中進(jìn)行異常的封裝并返回響應(yīng)結(jié)果。

4.2 進(jìn)行重寫

經(jīng)過(guò)源碼分析,我們需要重寫的有兩部分:

1.驗(yàn)證token (源碼中的key) 是否有效,之前是從數(shù)據(jù)庫(kù)進(jìn)行驗(yàn)證的現(xiàn)在需要通過(guò)redis去驗(yàn)證

2.重新封裝user模型對(duì)象,但有個(gè)問(wèn)題需要注意的是:
如果你重寫了django的user對(duì)象,讓它關(guān)聯(lián)了其他表的屬性,那么這里則不能將其封裝進(jìn)user這個(gè)對(duì)象的,因?yàn)閞edis不能存儲(chǔ)一個(gè)對(duì)象!,當(dāng)然如果非要這么做可以將外鍵id值在登錄 (寫入token) 的時(shí)候存入redis,然后在這里通過(guò)該外鍵id去查詢關(guān)聯(lián)的外鍵表獲取屬性,再封裝到user模型對(duì)象中!

重寫后的代碼

class RedisTokenAuthentication(TokenAuthentication):

    def authenticate_credentials(self, key):
        null = None  # json的None為null,所以需要定義一下
        user_data = redis_connect.get(key)
        if user_data:
            user_dict = json.loads(user_data)
            user_obj = User()
            for key_name in user_dict.keys():
                setattr(user_obj, key_name, user_dict[key_name])
            return user_obj, key
        raise exceptions.AuthenticationFailed(_('無(wú)效的token.'))

4.3 加入認(rèn)證配置

settings.py配置文件中,加入如下配置

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (  #如果有REST_FRAMEWORK配置項(xiàng)了單獨(dú)加入該項(xiàng)即可
        'Demo.RedisAuthentication.RedisTokenAuthentication',  # 項(xiàng)目名稱.重新認(rèn)證類所在的文件.類名
    ),
}

4.4 效果展示

增加一個(gè)接口

path('test-token', views.test_token),

接口方法代碼

@api_view(['GET'])
@permission_classes((permissions.IsAuthenticated,))
def test_token(request):
    """
    測(cè)試token
    """
    print('登錄的用戶名是:', request.user)
    res_data = {'data': {'status_code': 200}}
    return Response(**res_data)

輸出結(jié)果

登錄的用戶名是: admin

三、總結(jié)

無(wú)論是django還是restframework,他們的源碼和官方文檔在我看來(lái)是非常清晰的 (在我看的那么多官方文檔中算很清晰的了) 這里給DRF的團(tuán)隊(duì)點(diǎn)個(gè)贊?。?

到此這篇關(guān)于django restframework使用redis實(shí)現(xiàn)token認(rèn)證的文章就介紹到這了,更多相關(guān)django restframework token認(rèn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何實(shí)現(xiàn)在pycharm中將.ui文件轉(zhuǎn)化為.py文件

    如何實(shí)現(xiàn)在pycharm中將.ui文件轉(zhuǎn)化為.py文件

    這篇文章主要介紹了如何實(shí)現(xiàn)在pycharm中將.ui文件轉(zhuǎn)化為.py文件,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-06-06
  • pytorch簡(jiǎn)介

    pytorch簡(jiǎn)介

    Pytorch是torch的python版本,是由Facebook開源的神經(jīng)網(wǎng)絡(luò)框架,專門針對(duì) GPU 加速的深度神經(jīng)網(wǎng)絡(luò)(DNN)編程。這篇文章給大家介紹pytorch的相關(guān)知識(shí),感興趣的朋友一起看看吧
    2020-11-11
  • Python使用FTP上傳文件的實(shí)現(xiàn)示例

    Python使用FTP上傳文件的實(shí)現(xiàn)示例

    本文主要介紹了Python使用FTP上傳文件的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Java多線程編程中ThreadLocal類的用法及深入

    Java多線程編程中ThreadLocal類的用法及深入

    這篇文章主要介紹了Java多線程編程中ThreadLocal類的用法及深入,嘗試了自己實(shí)現(xiàn)一個(gè)ThreadLocal類以及對(duì)相關(guān)的線程安全問(wèn)題進(jìn)行討論,需要的朋友可以參考下
    2016-06-06
  • Python3.5文件修改操作實(shí)例分析

    Python3.5文件修改操作實(shí)例分析

    這篇文章主要介紹了Python3.5文件修改操作,結(jié)合實(shí)例形式分析了Python3.5針對(duì)txt文本文件的讀寫、修改等相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • python 用 xlwings 庫(kù) 生成圖表的操作方法

    python 用 xlwings 庫(kù) 生成圖表的操作方法

    這篇文章主要介紹了python 用 xlwings 庫(kù) 生成圖表的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Python使用Django實(shí)現(xiàn)博客系統(tǒng)完整版

    Python使用Django實(shí)現(xiàn)博客系統(tǒng)完整版

    這篇文章主要為大家詳細(xì)介紹了Python利用Django完整的開發(fā)一個(gè)博客系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • NumPy 數(shù)組使用大全

    NumPy 數(shù)組使用大全

    這篇文章主要介紹了NumPy 數(shù)組使用大全,在本教程中,你將學(xué)習(xí)如何在 NumPy 數(shù)組上以多種方式添加、刪除、排序和操作元素。 文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • pandas實(shí)現(xiàn)對(duì)一列/多列進(jìn)行數(shù)據(jù)區(qū)間篩選

    pandas實(shí)現(xiàn)對(duì)一列/多列進(jìn)行數(shù)據(jù)區(qū)間篩選

    這篇文章主要介紹了pandas實(shí)現(xiàn)對(duì)一列/多列進(jìn)行數(shù)據(jù)區(qū)間篩選方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Pandas之排序函數(shù)sort_values()的實(shí)現(xiàn)

    Pandas之排序函數(shù)sort_values()的實(shí)現(xiàn)

    這篇文章主要介紹了Pandas之排序函數(shù)sort_values()的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07

最新評(píng)論