您好,登錄后才能下訂單哦!
這篇文章主要介紹“使用Django如何實(shí)現(xiàn)微信小程序的登錄驗(yàn)證功能”,在日常操作中,相信很多人在使用Django如何實(shí)現(xiàn)微信小程序的登錄驗(yàn)證功能問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”使用Django如何實(shí)現(xiàn)微信小程序的登錄驗(yàn)證功能”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
環(huán)境說(shuō)明:
1、小程序只需要拿到openid,其他信息不存儲(chǔ)。
2、Django自帶的User類不適合。
具體操作流程:
1、用戶點(diǎn)進(jìn)小程序,就調(diào)用wx.login()
獲取臨時(shí)登錄憑證code, wx.login()
用戶是無(wú)感知的,
2、通過(guò)wx.request()
將code傳到開發(fā)者服務(wù)器的后臺(tái)程序,
3、后臺(tái)拿到code之后,調(diào)用微信提供的接口,獲取openid和session_key,
4、后臺(tái)自定義User表,將openid作為用戶名,不設(shè)置用戶密碼,如果用戶不存在,則創(chuàng)建新用戶,接著根據(jù)openid和session_key生成新的自定義登錄態(tài)3rd_session(這里使用skey表示)返回給小程序,
5、后臺(tái)將skey存入緩存中(Redis),設(shè)置為2小時(shí)過(guò)期,
6、小程序接收到skey,說(shuō)明登錄成功,將skey保存到本地Storage中,下次請(qǐng)求時(shí),在請(qǐng)求頭中攜帶skey,
7、后臺(tái)接收到請(qǐng)求,從請(qǐng)求頭中拿到skey,判斷緩存中是否還有此skey,如果有,說(shuō)明還在登錄態(tài),允許執(zhí)行請(qǐng)求相關(guān)操作,如果沒(méi)有,說(shuō)明需要重新登錄,給小程序返回401.
第三方庫(kù): 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è)計(jì)
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: # 有錯(cuò)誤碼 return Response(data={'code':response['errcode'], 'msg': response['errmsg']}) # 登錄成功 openid = response['openid'] session_key = response['session_key'] # 保存openid, 需要先判斷數(shù)據(jù)庫(kù)中有沒(méi)有這個(gè)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)保存到緩存中, 兩個(gè)小時(shí)過(guò)期 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給小程序端,小程序保存到本地,下次請(qǐng)求攜帶skey。
用戶登錄認(rèn)證
因?yàn)槲业腢ser類是自定義的,skey也是自定義的,沒(méi)有使用token或者jwt等技術(shù),這里就需要自定義登錄認(rèn)證了,在執(zhí)行視圖里相應(yīng)的請(qǐng)求處理函數(shù)前,先對(duì)skey做判斷,判斷通過(guò)就從skey中取得openid的值。
我在這里考慮了幾種方法:
1、利用Django中間件,
2、利用裝飾器,
3、利用rest_framework的認(rèn)證類,
這里先分析Django的請(qǐng)求處理流程:
從上圖也可以看出,在中間件中做認(rèn)證,完全是可行的,認(rèn)證不通過(guò)就可以直接返回了,不用到達(dá)路由映射表和視圖。但是rest_framework中,對(duì)request進(jìn)行了封裝,中間件中的request是django的HttpRequest,而rest_framework將django的request封裝成rest_framework的Request
。
如果是裝飾器的話,在本次設(shè)計(jì)中不夠靈活,因?yàn)槌说卿浗涌?,其他接口的每個(gè)method都需要做認(rèn)證。
所以綜合考慮,自定義一個(gè)rest_framework的認(rèn)證類是最適合這次小程序的驗(yàn)證的,在認(rèn)證類中設(shè)置request.user,然后在視圖中就可以通過(guò)request.user直接獲取用戶信息了。
接下來(lái),先分析一下rest_framework的源碼,看看是怎么做認(rèn)證的。
從上圖源碼分析中,可以看出最后是調(diào)用了認(rèn)證類的認(rèn)證方法:authenticator.authenticate().
然后先看看rest_framework自帶的認(rèn)證類,在rest_framework.authentication
中,
接下來(lái)就自定義一個(gè)適用于本次小程序設(shè)計(jì)的認(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已過(guò)期'}) else: raise exceptions.AuthenticationFailed(detail={'code': 400, 'msg': '缺少skey'}) def authenticate_header(self, request): return 'skey'
最后利用全局設(shè)置DEFAULT_AUTHENTICATION_CLASSE
將UserAuthentication
設(shè)置為全局使用,同時(shí)登錄接口應(yīng)該設(shè)計(jì)為不使用認(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: # 有錯(cuò)誤碼 return Response(data={'code':response['errcode'], 'msg': response['errmsg']}) # 登錄成功 openid = response['openid'] session_key = response['session_key'] # 保存openid, 需要先判斷數(shù)據(jù)庫(kù)中有沒(méi)有這個(gè)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)保存到緩存中, 兩個(gè)小時(shí)過(guò)期 conn = get_redis_connection('default') conn.set(digest, user_str, ex=2*60*60) return Response(data={'code': 200, 'msg': 'ok', 'data': {'skey': digest})
到此,關(guān)于“使用Django如何實(shí)現(xiàn)微信小程序的登錄驗(yàn)證功能”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。