觸屏版網(wǎng)站開發(fā)樣式互聯(lián)網(wǎng)推廣與營銷
教程:在Django中實(shí)現(xiàn)微信授權(quán)登錄
本教程將引導(dǎo)您如何在Django項(xiàng)目中實(shí)現(xiàn)微信授權(quán)登錄。在本教程中,我們將使用自定義的用戶模型User
,并通過微信提供的API來進(jìn)行用戶認(rèn)證。
在進(jìn)行以下教程之前,請(qǐng)確保你已經(jīng)在微信開放平臺(tái)添加了網(wǎng)站應(yīng)用,并獲得了:
1.WECHAT_APPID
2.WECHAT_SECRET
3.以及設(shè)置了回調(diào)域(即認(rèn)證的網(wǎng)址)
WECHAT_REDIRECT_URI 比如,我的回調(diào)域就是:https://www.xxx.com,Django的url中我則寫成/wechat/callback/,視圖中就可以進(jìn)行回調(diào)使用了,這個(gè)沒有絕對(duì),重要的是設(shè)置自己的網(wǎng)址為回調(diào)域
第1步:創(chuàng)建自定義用戶模型
首先,在您的Django應(yīng)用中創(chuàng)建一個(gè)自定義的用戶模型。在models.py
文件中定義模型:
from django.db import models# 這里一定要繼承AbstractUser才行
from django.contrib.auth.models import AbstractUserclass User(AbstractUser):# 不需要顯式添加id字段,Django會(huì)自動(dòng)創(chuàng)建openid = models.CharField(max_length=128, unique=True, null=True, blank=True)username = models.CharField(max_length=150, null=True, unique=True)# 不需要再次聲明password字段,因?yàn)锳bstractUser類已經(jīng)包含了password字段# email字段已在AbstractUser中定義,只需指定null和blank即可email = models.EmailField(null=True, blank=True)phone_number = models.CharField(max_length=15, null=True, blank=True)real_name = models.CharField(max_length=128, null=True, blank=True)creation_date = models.DateTimeField(auto_now_add=True)role_type = models.CharField(max_length=50, null=True, blank=True)avatar = models.URLField(null=True, blank=True)gender = models.CharField(max_length=10, null=True, blank=True)birthday = models.DateField(null=True, blank=True)address = models.CharField(max_length=255, null=True, blank=True)# 新增加的微信字段nickname = models.CharField(max_length=64, null=True, blank=True)sex = models.PositiveSmallIntegerField(choices=((0, '未知'), (1, '男'), (2, '女')), null=True, blank=True)language = models.CharField(max_length=32, null=True, blank=True)city = models.CharField(max_length=32, null=True, blank=True)province = models.CharField(max_length=32, null=True, blank=True)country = models.CharField(max_length=32, null=True, blank=True)headimgurl = models.URLField(null=True, blank=True)privilege = models.JSONField(default=list, blank=True, null=True) # 使用可調(diào)用的默認(rèn)值unionid = models.CharField(max_length=128, null=True, blank=True)# last_login字段已經(jīng)在AbstractBaseUser中,不需要重復(fù)聲明# 如果你沒有特別需要覆蓋save()方法,也可以省略這個(gè)方法# def save(self, *args, **kwargs):# super(User, self).save(*args, **kwargs)@classmethoddef create_or_update_from_wechat(cls, wechat_data):user, created = cls.objects.update_or_create(openid=wechat_data['openid'],defaults={'nickname': wechat_data.get('nickname', ''),'sex': wechat_data.get('sex', 0),'language': wechat_data.get('language', ''),'city': wechat_data.get('city', ''),'province': wechat_data.get('province', ''),'country': wechat_data.get('country', ''),'headimgurl': wechat_data.get('headimgurl', ''),'privilege': wechat_data.get('privilege', []),'unionid': wechat_data.get('unionid', ''),})return user
第2步:配置settings.py
在settings.py
文件中進(jìn)行以下配置:
# 登錄認(rèn)證系統(tǒng)后端,二者任選其一即可
AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend','allauth.account.auth_backends.AuthenticationBackend',
]# index 是應(yīng)用的名字,User 是你的自定義用戶模型的類名
AUTH_USER_MODEL = 'index.User'# 用戶登錄的url名稱
LOGIN_URL = "user_login"# 登錄成功調(diào)回地址的url名稱
LOGIN_REDIRECT_URL = "index"
第3步:實(shí)現(xiàn)登錄視圖
在views.py
中創(chuàng)建登錄視圖和微信回調(diào)視圖:
from django.shortcuts import redirect
from django.conf import settings
import requests
from urllib.parse import quote
from django.http import HttpResponseRedirect
from django.contrib.auth import logout
from django.http import JsonResponse
from .models import User
from django.contrib.auth import login
from django.utils import timezonedef user_login(request):appid = settings.WECHAT_APPIDredirect_uri = quote(settings.WECHAT_REDIRECT_URI)url = f"https://open.weixin.qq.com/connect/qrconnect?appid={appid}&redirect_uri={redirect_uri}&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect"return HttpResponseRedirect(url)def logout_view(request):logout(request)# 重定向到登錄頁面或者主頁return redirect('index')def wechat_login_callback(request):code = request.GET.get('code')# 利用code獲取access_tokenappid = settings.WECHAT_APPIDsecret = settings.WECHAT_SECRETurl = f'https://api.weixin.qq.com/sns/oauth2/access_token?appid={appid}&secret={secret}&code={code}&grant_type=authorization_code'response = requests.get(url)data = response.json()access_token = data.get('access_token')openid = data.get('openid')url = f'https://api.weixin.qq.com/sns/userinfo?access_token={access_token}&openid={openid}'response = requests.get(url)user_info = response.json()# 創(chuàng)建或者更新用戶信息user = User.create_or_update_from_wechat(user_info)# 更新 last_login 字段user.last_login = timezone.now()user.save(update_fields=['last_login'])# 選擇要登錄的后端認(rèn)證系統(tǒng),這里可以選擇Django自帶的,也可以選擇微信的backend = 'django.contrib.auth.backends.ModelBackend'# backend = 'allauth.account.auth_backends.AuthenticationBackend'user.backend = backend # 設(shè)置用戶實(shí)例的后端屬性login(request, user, backend=backend) # 登錄用戶,傳入backend參數(shù)# 這里我隨便寫了一個(gè)url名稱return redirect("bbworld")
第4步:配置URLs
在urls.py
中將路徑與視圖關(guān)聯(lián)起來:
from django.urls import path
from . import viewsurlpatterns = [path('login/', views.user_login, name='user_login'),path('logout/', views.logout_view, name='logout'),path('wechat/callback/', views.wechat_login_callback, name='wechat_callback'),# 其他URLs...
]
第5步:使用@login_required裝飾器保護(hù)視圖
在任何需要用戶登錄的視圖前使用@login_required
裝飾器:
from django.shortcuts import render
from django.contrib.auth.decorators import login_required@login_required
def bbworld(request):return render(request, 'bbworld.html')
第6步:處理未登錄的重定向
當(dāng)用戶嘗試訪問受@login_required
保護(hù)的頁面時(shí),他們將被重定向到在settings.py
中定義的LOGIN_URL
,然后授權(quán)登錄成功后反調(diào)回LOGIN_REDIRECT_URL = “index”。
在Django中,當(dāng)您對(duì)模型進(jìn)行了更改之后,例如添加了新的字段或修改了字段的類型,您需要?jiǎng)?chuàng)建一個(gè)新的數(shù)據(jù)庫遷移以便將這些更改應(yīng)用到數(shù)據(jù)庫中。以下是如何進(jìn)行數(shù)據(jù)遷移的步驟:
第7步:數(shù)據(jù)遷移到數(shù)據(jù)庫
這一步也可以建好模型的時(shí)候就進(jìn)行操作,另外,確保setting里面已經(jīng)設(shè)置好了數(shù)據(jù)庫,無論是sqlite還是mysql
python manage.py makemigrations
python manage.py migrate
第8步:運(yùn)行和測(cè)試
運(yùn)行您的Django項(xiàng)目并測(cè)試登錄流程。確保所有URLs正確配置,并且重定向和回調(diào)都按預(yù)期工作。
python manage.py runserver
訪問登錄URL,并通過微信掃碼登錄來測(cè)試整個(gè)流程。
以上就是在Django中實(shí)現(xiàn)微信授權(quán)登錄的基本步驟。
因?yàn)檫@個(gè)事情,花了我很多時(shí)間,我也希望你能通過我的教程,快速完成業(yè)務(wù),如果有不清楚的,歡迎留言咨詢,我會(huì)第一時(shí)間回復(fù),謝謝,祝你也學(xué)習(xí)愉快!