中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用Django如何實現微信小程序的登錄驗證功能

發布時間:2022-04-20 15:28:40 來源:億速云 閱讀:550 作者:iii 欄目:大數據

這篇文章主要介紹“使用Django如何實現微信小程序的登錄驗證功能”,在日常操作中,相信很多人在使用Django如何實現微信小程序的登錄驗證功能問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”使用Django如何實現微信小程序的登錄驗證功能”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

環境說明:

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

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

具體操作流程:

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

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

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

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

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

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

7、后臺接收到請求,從請求頭中拿到skey,判斷緩存中是否還有此skey,如果有,說明還在登錄態,允許執行請求相關操作,如果沒有,說明需要重新登錄,給小程序返回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__'

登錄接口設計

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數據包轉成字典
 if 'errcode' in response:
 # 有錯誤碼
 return Response(data={'code':response['errcode'], 'msg': response['errmsg']})
 # 登錄成功
 openid = response['openid']
 session_key = response['session_key']
 # 保存openid, 需要先判斷數據庫中有沒有這個openid
 user, created = User.objects.get_or_create(openid=openid)
 user_str = str(UserSerializer(user).data)
 # 生成自定義登錄態,返回給前端
 sha = hashlib.sha1()
 sha.update(openid.encode())
 sha.update(session_key.encode())
 digest = sha.hexdigest()
 # 將自定義登錄態保存到緩存中, 兩個小時過期
 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。

用戶登錄認證

因為我的User類是自定義的,skey也是自定義的,沒有使用token或者jwt等技術,這里就需要自定義登錄認證了,在執行視圖里相應的請求處理函數前,先對skey做判斷,判斷通過就從skey中取得openid的值。

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

1、利用Django中間件,

2、利用裝飾器,

3、利用rest_framework的認證類,

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

使用Django如何實現微信小程序的登錄驗證功能

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

如果是裝飾器的話,在本次設計中不夠靈活,因為除了登錄接口,其他接口的每個method都需要做認證。

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

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

使用Django如何實現微信小程序的登錄驗證功能

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

使用Django如何實現微信小程序的登錄驗證功能

接下來就自定義一個適用于本次小程序設計的認證類: 新建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'

最后利用全局設置DEFAULT_AUTHENTICATION_CLASSEUserAuthentication設置為全局使用,同時登錄接口應該設計為不使用認證類,將登錄接口添加兩行代碼。

settings.py文件:

REST_FRAMEWORK = {
 'DEFAULT_AUTHENTICATION_CLASSES': (
 'note.authentication.UserAuthentication', # 用自定義的認證類
 ),
 '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數據包轉成字典
 if 'errcode' in response:
 # 有錯誤碼
 return Response(data={'code':response['errcode'], 'msg': response['errmsg']})
 # 登錄成功
 openid = response['openid']
 session_key = response['session_key']
 # 保存openid, 需要先判斷數據庫中有沒有這個openid
 user, created = User.objects.get_or_create(openid=openid)
 user_str = str(UserSerializer(user).data)
 # 生成自定義登錄態,返回給前端
 sha = hashlib.sha1()
 sha.update(openid.encode())
 sha.update(session_key.encode())
 digest = sha.hexdigest()
 # 將自定義登錄態保存到緩存中, 兩個小時過期
 conn = get_redis_connection('default')
 conn.set(digest, user_str, ex=2*60*60)
 return Response(data={'code': 200, 'msg': 'ok', 'data': {'skey': digest})

到此,關于“使用Django如何實現微信小程序的登錄驗證功能”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

镇远县| 汉沽区| 井陉县| 漳浦县| 翁牛特旗| 芷江| 伊宁市| 左贡县| 巴彦县| 楚雄市| 准格尔旗| 寿阳县| 古蔺县| 武隆县| 澄城县| 萨迦县| 余姚市| 洛扎县| 隆昌县| 肥乡县| 平阳县| 信宜市| 寻乌县| 蒙山县| 登封市| 武陟县| 辽阳县| 木兰县| 安岳县| 龙州县| 枞阳县| 家居| 康定县| 甘南县| 绥江县| 永城市| 朝阳县| 孝昌县| 龙江县| 祁东县| 白沙|