最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django實(shí)現(xiàn)微信小程序的登錄驗(yàn)證功能并維護(hù)登錄態(tài)

 更新時間:2019年07月04日 16:01:03   作者:門牙  
這篇文章主要介紹了Django實(shí)現(xiàn)小程序的登錄驗(yàn)證功能并維護(hù)登錄態(tài),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下

這次自己做了一個小程序來玩,在登錄方面一直有些模糊,網(wǎng)上看了很多文檔后,得出以下一種解決方案。

環(huán)境說明:

1、小程序只需要拿到openid,其他信息不存儲。

2、Django自帶的User類不適合。

具體操作流程:

1、用戶點(diǎn)進(jìn)小程序,就調(diào)用wx.login()獲取臨時登錄憑證code, wx.login()用戶是無感知的,

2、通過wx.request()將code傳到開發(fā)者服務(wù)器的后臺程序,

3、后臺拿到code之后,調(diào)用微信提供的接口,獲取openid和session_key,

4、后臺自定義User表,將openid作為用戶名,不設(shè)置用戶密碼,如果用戶不存在,則創(chuàng)建新用戶,接著根據(jù)openid和session_key生成新的自定義登錄態(tài)3rd_session(這里使用skey表示)返回給小程序,

5、后臺將skey存入緩存中(Redis),設(shè)置為2小時過期,

6、小程序接收到skey,說明登錄成功,將skey保存到本地Storage中,下次請求時,在請求頭中攜帶skey,

7、后臺接收到請求,從請求頭中拿到skey,判斷緩存中是否還有此skey,如果有,說明還在登錄態(tài),允許執(zhí)行請求相關(guān)操作,如果沒有,說明需要重新登錄,給小程序返回401.

第三方庫: Django、Djando rest framework、Django-redis

用戶信息

自定義User類

models.py

from django.db import models
from django.utils import timezone
class User(models.Model):
 openid = models.CharField(max_length=50, unique=True)
 created_date = models.DateTimeField(auto_now_add=True)

User接口序列化

serializers.py

from rest_framework import serializers
from django.utils import timezone
from .models import User
class UserSerializer(serializers.ModelSerializer):
 class Meta:
 model = User
 fields = '__all__'

登錄接口設(shè)計

views.py

import hashlib
import json
import requests
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django_redis import get_redis_connection
from .models import User
from .serializers import UserSerializer
@api_view(['POST'])
def code2Session(request):
 appid = ''
 secret = ''
 js_code = request.data['code']
 url = 'https://api.weixin.qq.com/sns/jscode2session' + '?appid=' + appid + '&secret=' + secret + '&js_code=' + js_code + '&grant_type=authorization_code'
 response = json.loads(requests.get(url).content) # 將json數(shù)據(jù)包轉(zhuǎn)成字典
 if 'errcode' in response:
 # 有錯誤碼
 return Response(data={'code':response['errcode'], 'msg': response['errmsg']})
 # 登錄成功
 openid = response['openid']
 session_key = response['session_key']
 # 保存openid, 需要先判斷數(shù)據(jù)庫中有沒有這個openid
 user, created = User.objects.get_or_create(openid=openid)
 user_str = str(UserSerializer(user).data)
 # 生成自定義登錄態(tài),返回給前端
 sha = hashlib.sha1()
 sha.update(openid.encode())
 sha.update(session_key.encode())
 digest = sha.hexdigest()
 # 將自定義登錄態(tài)保存到緩存中, 兩個小時過期
 conn = get_redis_connection('default')
 conn.set(digest, user_str, ex=2*60*60)
 return Response(data={'code': 200, 'msg': 'ok', 'data': {'skey': digest})

其中,redis的安裝,配置與使用,可以參考這篇文檔。

登錄后,返回skey給小程序端,小程序保存到本地,下次請求攜帶skey。

用戶登錄認(rèn)證

因?yàn)槲业腢ser類是自定義的,skey也是自定義的,沒有使用token或者jwt等技術(shù),這里就需要自定義登錄認(rèn)證了,在執(zhí)行視圖里相應(yīng)的請求處理函數(shù)前,先對skey做判斷,判斷通過就從skey中取得openid的值。

我在這里考慮了幾種方法:

1、利用Django中間件,

2、利用裝飾器,

3、利用rest_framework的認(rèn)證類,

這里先分析Django的請求處理流程:

從上圖也可以看出,在中間件中做認(rèn)證,完全是可行的,認(rèn)證不通過就可以直接返回了,不用到達(dá)路由映射表和視圖。但是rest_framework中,對request進(jìn)行了封裝,中間件中的request是django的HttpRequest,而rest_framework將django的request封裝成rest_framework的Request

如果是裝飾器的話,在本次設(shè)計中不夠靈活,因?yàn)槌说卿浗涌?,其他接口的每個method都需要做認(rèn)證。

所以綜合考慮,自定義一個rest_framework的認(rèn)證類是最適合這次小程序的驗(yàn)證的,在認(rèn)證類中設(shè)置request.user,然后在視圖中就可以通過request.user直接獲取用戶信息了。

接下來,先分析一下rest_framework的源碼,看看是怎么做認(rèn)證的。

從上圖源碼分析中,可以看出最后是調(diào)用了認(rèn)證類的認(rèn)證方法:authenticator.authenticate(). 然后先看看rest_framework自帶的認(rèn)證類,在rest_framework.authentication中,

接下來就自定義一個適用于本次小程序設(shè)計的認(rèn)證類: 新建authentication.py文件

from rest_framework import exceptions
from rest_framework.authentication import BaseAuthentication
from django_redis import get_redis_connection
class UserAuthentication(BaseAuthentication):
 def authenticate(self, request):
 if 'HTTP_SKEY' in request.META:
  skey = request.META['HTTP_SKEY']
  conn = get_redis_connection('default')
  if conn.exists(skey):
  user = conn.get(skey) 
  return (user, skey)
  else:
  raise exceptions.AuthenticationFailed(detail={'code': 401, 'msg': 'skey已過期'})
 else:
  raise exceptions.AuthenticationFailed(detail={'code': 400, 'msg': '缺少skey'})
 def authenticate_header(self, request):
 return 'skey'

最后利用全局設(shè)置DEFAULT_AUTHENTICATION_CLASSEUserAuthentication設(shè)置為全局使用,同時登錄接口應(yīng)該設(shè)計為不使用認(rèn)證類,將登錄接口添加兩行代碼。

settings.py文件:

REST_FRAMEWORK = {
 'DEFAULT_AUTHENTICATION_CLASSES': (
 'note.authentication.UserAuthentication', # 用自定義的認(rèn)證類
 ),
 'DEFAULT_RENDERER_CLASSES': (
 'rest_framework.renderers.JSONRenderer',
 ),
 'DEFAULT_PARSER_CLASSES': (
 'rest_framework.parsers.JSONParser',
 ),
}

登錄接口

import hashlib
import json
import requests
from rest_framework import status
from rest_framework.decorators import api_view, authentication_classes
from rest_framework.response import Response
from django_redis import get_redis_connection
from .models import User
from .serializers import UserSerializer
@api_view(['POST'])
@authentication_classes([]) # 添加
def code2Session(request):
 appid = ''
 secret = ''
 js_code = request.data['code']
 url = 'https://api.weixin.qq.com/sns/jscode2session' + '?appid=' + appid + '&secret=' + secret + '&js_code=' + js_code + '&grant_type=authorization_code'
 response = json.loads(requests.get(url).content) # 將json數(shù)據(jù)包轉(zhuǎn)成字典
 if 'errcode' in response:
 # 有錯誤碼
 return Response(data={'code':response['errcode'], 'msg': response['errmsg']})
 # 登錄成功
 openid = response['openid']
 session_key = response['session_key']
 # 保存openid, 需要先判斷數(shù)據(jù)庫中有沒有這個openid
 user, created = User.objects.get_or_create(openid=openid)
 user_str = str(UserSerializer(user).data)
 # 生成自定義登錄態(tài),返回給前端
 sha = hashlib.sha1()
 sha.update(openid.encode())
 sha.update(session_key.encode())
 digest = sha.hexdigest()
 # 將自定義登錄態(tài)保存到緩存中, 兩個小時過期
 conn = get_redis_connection('default')
 conn.set(digest, user_str, ex=2*60*60)
 return Response(data={'code': 200, 'msg': 'ok', 'data': {'skey': digest})

之后,在接口中通過request.user就可以取到本次請求的用戶信息了。

總結(jié)

以上所述是小編給大家介紹的Django實(shí)現(xiàn)微信小程序的登錄驗(yàn)證功能并維護(hù)登錄態(tài),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!

相關(guān)文章

  • python使用PyGame實(shí)現(xiàn)打磚塊游戲

    python使用PyGame實(shí)現(xiàn)打磚塊游戲

    打磚塊也是一個非常經(jīng)典的小游戲,玩法大致如下,用一個小車接一個小球,然后反射小球,使之打在磚塊上,當(dāng)小球碰到磚塊之后,則磚塊被消掉,邏輯十分清晰,本文將給大家介紹了python使用PyGame實(shí)現(xiàn)打磚塊游戲,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2023-12-12
  • python 域名分析工具實(shí)現(xiàn)代碼

    python 域名分析工具實(shí)現(xiàn)代碼

    用python實(shí)現(xiàn)域名分析,數(shù)據(jù)來源金玉米
    2009-07-07
  • Pandas.DataFrame時間序列數(shù)據(jù)處理的實(shí)現(xiàn)

    Pandas.DataFrame時間序列數(shù)據(jù)處理的實(shí)現(xiàn)

    本文主要介紹了Pandas.DataFrame時間序列數(shù)據(jù)處理的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 使用Python3實(shí)現(xiàn)判斷函數(shù)的圈復(fù)雜度

    使用Python3實(shí)現(xiàn)判斷函數(shù)的圈復(fù)雜度

    編寫函數(shù)最重要的原則就是:別寫太復(fù)雜的函數(shù),那什么樣的函數(shù)才能算是過于復(fù)雜?一般會通過兩個標(biāo)準(zhǔn)來判斷,長度和圈復(fù)雜度,下面我們就來看看如何使用Python判斷函數(shù)的圈復(fù)雜度吧
    2024-04-04
  • Pytorch閱讀文檔中的flatten函數(shù)

    Pytorch閱讀文檔中的flatten函數(shù)

    PyTorch提供了一個非常方便的函數(shù)flatten()來完成這個任務(wù),本文將介紹Pytorch閱讀文檔中的flatten函數(shù),并提供一些示例代碼,感興趣的朋友一起看看吧
    2023-11-11
  • 用Django寫天氣預(yù)報查詢網(wǎng)站

    用Django寫天氣預(yù)報查詢網(wǎng)站

    今天小編就為大家分享一篇關(guān)于用Django寫天氣預(yù)報查詢網(wǎng)站的文章,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • python排序的方法實(shí)例總結(jié)

    python排序的方法實(shí)例總結(jié)

    在本篇文章里小編給大家整理的是一篇關(guān)于python排序的方法實(shí)例總結(jié)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-04-04
  • centos 安裝Python3 及對應(yīng)的pip教程詳解

    centos 安裝Python3 及對應(yīng)的pip教程詳解

    這篇文章主要介紹了centos 安裝Python3 及對應(yīng)的pip的教程,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • 詳解Python如何制作自動發(fā)送微信的程序

    詳解Python如何制作自動發(fā)送微信的程序

    這篇文章主要介紹了如何利用Python中的apscheduler和pyautogui模塊,制作一個自動發(fā)送微信的程序。感興趣的小伙伴可以跟隨小編一起動手試一試
    2022-01-01
  • 深入Python解釋器理解Python中的字節(jié)碼

    深入Python解釋器理解Python中的字節(jié)碼

    這篇文章深入Python解釋器、從其對字節(jié)碼的處理過程來詳解Python中的字節(jié)碼,需要的朋友可以參考下
    2015-04-04

最新評論

中宁县| 洮南市| 秦皇岛市| 射阳县| 临朐县| 炉霍县| 弥渡县| 蒲城县| 迁安市| 华蓥市| 宜昌市| 准格尔旗| 东宁县| 富顺县| 昌都县| 青冈县| 潮安县| 吴忠市| 南漳县| 渭南市| 廊坊市| 多伦县| 霍山县| 高唐县| 都兰县| 外汇| 肇东市| 姜堰市| 无极县| 论坛| 志丹县| 拜城县| 万山特区| 峨边| 济源市| 鹤岗市| 土默特左旗| 车致| 博罗县| 伊金霍洛旗| 隆化县|