!
🏆🏆🏆教程全知識點簡介:1.郵件驗證系統包括Django發送郵件、保存郵箱併發送驗證郵件、Celery使用Django配置文件設置。2. 地址管理涵蓋收貨地址、省市區地址查詢、數據庫建表、後端接口設計、前端實現、緩存使用(安裝、使用方法、省市區視圖緩存、緩存數據保存位置和有效期設置)、用户地址管理。3. 數據庫設計包括用户部分、商品部分、數據庫表設計、表結構、數據庫模型類。4. 容器化部署涵蓋Docker使用(Ubuntu安裝、啓動停止、鏡像操作)、FastDFS客户端與自定義文件存儲系統、頁面靜態化、定時任務、靜態化首頁腳本。5. 商品系統包括商品詳情頁、異步任務觸發、腳本工具、用户瀏覽歷史記錄(保存、查看)。6. 商業模式涵蓋B2B企業對企業、C2C個人對個人、O2O線上到線下、開發流程、需求分析。7. 購物車系統包括購物車管理、購物車數據存儲設計(Redis保存已登錄用户)、添加到購物車、查詢購物車數據、登錄合併購物車。8. 訂單系統涵蓋提交訂單、我的訂單、訂單評價、訂單結算、保存訂單、MySQL事務隔離級別修改、下單成功頁面。9. 搜索系統包括商品搜索、搜索引擎原理、Elasticsearch、Docker安裝Elasticsearch擴展、前端實現。10. 支付系統涉及 集成、Xadmin管理後台。11. 項目配置包括項目準備、配置文件修改、數據庫配置、Redis配置、本地化語言時區、異常處理、日誌記錄。12. 用户認證系統涵蓋圖片驗證碼、域名設置、前端Vue代碼、跨域CORS、Celery發送短信、賬號存在判斷、JWT認證(JWT概念、構成、應用、Django REST framework JWT)、 登錄(登錄流程、模型類創建、urllib使用、回調處理)、用户中心個人信息。
<!-- start:bj1 -->
📚📚👉👉👉本站這篇博客: https://segmentfault.com/a/1190000046826591 中查看
📚📚👉👉👉本站這篇博客: https://segmentfault.com/a/1190000047166553 中查看
<!-- end:bj1 -->
✨ 本教程項目亮點
🧠 知識體系完整:覆蓋從基礎原理、核心方法到高階應用的全流程內容
💻 全技術鏈覆蓋:完整前後端技術棧,涵蓋開發必備技能
🚀 從零到實戰:適合 0 基礎入門到提升,循序漸進掌握核心能力
📚 豐富文檔與代碼示例:涵蓋多種場景,可運行、可複用
🛠 工作與學習雙參考:不僅適合系統化學習,更可作為日常開發中的查閲手冊
🧩 模塊化知識結構:按知識點分章節,便於快速定位和複習
📈 長期可用的技術積累:不止一次學習,而是能伴隨工作與項目長期參考
🎯🎯🎯全教程總章節
🚀🚀🚀本篇主要內容
登錄
登錄,亦即我們所説的第三方登錄,是指用户可以不在本項目中輸入 ,而直接通過第三方的驗證,成功登錄本項目。
若想實現登錄,需要成為互聯的開發者,審核通過才可實現。註冊方法可參考鏈接http://wiki.connect.qq.com/%E6%88%90%E4%B8%BA%E5%BC%80%E5%8F%91%E8%80%85
成為互聯開發者後,還需創建應用,即獲取本項目對應與互聯的應用ID,創建應用的方法參考鏈接http://wiki.connect.qq.com/__trashed-2
登錄開發文檔連接http://wiki.connect.qq.com/%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C_oauth2-0
使用登錄的流程
創建模型類
創建一個新的應用oauth,用來實現第三方認證登錄。總路由前綴 oauth/
在meiduo/meiduo_mall/utils/models.py文件中創建模型類基類,用於增加數據新建時間和更新時間。
from django.db import models
class BaseModel(models.Model):
"""為模型類補充字段"""
create_time = models.DateTimeField(auto_now_add=True, verbose_name="創建時間")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新時間")
class Meta:
abstract = True # 説明是抽象模型類, 用於繼承使用,數據庫遷移時不會創建BaseModel的表
在oauth/models.py中定義身份(openid)與用户模型類User的關聯關係
from django.db import models
from meiduo_mall.utils.models import BaseModel
class OAuthUser(BaseModel):
"""
登錄用户數據
"""
user = models.ForeignKey('users.User', on_delete=models.CASCADE, verbose_name='用户')
openid = models.CharField(max_length=64, verbose_name='openid', db_index=True)
class Meta:
db_table = 'tb_oauth_qq'
verbose_name = '登錄用户數據'
verbose_name_plural = verbose_name
進行數據庫遷移
python manage.py makemigrations
python manage.py migrate
urllib使用説明
在後端接口中,我們需要向服務器發送請求,查詢用户的信息,Python提供了標準模塊urllib可以幫助我們發送http請求。
- urllib.parse.urlencode(query)
將query字典轉換為url路徑中的查詢字符串
- urllib.parse.parse_qs(qs)
將qs查詢字符串格式數據轉換為python的字典
- urllib.request.urlopen(url, data=None)
發送http請求,如果data為None,發送GET請求,如果data不為None,發送POST請求
返回response響應對象,可以通過read()讀取響應體數據,需要注意讀取出的響應體數據為bytes類型
綁定用户身份接口
如果用户是首次使用登錄,則需要綁定用户,頁面如下:
業務邏輯:
json 文檔
- 用户需要填寫手機號、 、圖片、
- 如果用户未在美多mall註冊過,則會將手機號作為用户名為用户創建一個美多賬户,並綁定用户
- 如果用户已在美多mall註冊過,則檢驗 後直接綁定用户
綁定身份的處理流程
後端接口設計
請求方式: POST /oauth/qq/user/
請求參數: JSON 或 表單
| 參數 | 類型 | 是否必須 | 説明 |
|---|---|---|---|
| mobile | str | 是 | 手機號 |
| password | str | 是 | |
| sms_code | str | 是 | |
| access_token | str | 是 | 憑據 (包含openid) |
返回數據: JSON
| 返回值 | 類型 | 是否必須 | 説明 |
|---|---|---|---|
| token | str | 是 | JWT token |
| user_id | int | 是 | 用户id |
| username | str | 是 | 用户名 |
在OAuth輔助類中增加
@staticmethod
def check_save_user_token(token):
"""
檢驗保存用户數據的token
:param token: token
:return: openid or None
"""
serializer = Serializer(settings.SECRET_KEY, expires_in=constants.SAVE__USER_TOKEN_EXPIRES)
try:
data = serializer.loads(token)
except BadData:
return None
else:
return data.get('openid')
新建oauth/serializers.py文件,
class OAuthUserSerializer(serializers.Serializer):
"""
登錄創建用户序列化器
"""
access_token = serializers.CharField(label='操作憑證')
mobile = serializers.RegexField(label='手機號', regex=r'^1[3-9]\d{9}$')
password = serializers.CharField(label=' ', max_length=20, min_length=8)
sms_code = serializers.CharField(label='')
def validate(self, data):
# 檢驗access_token
access_token = data['access_token']
openid = OAuth.check_save_user_token(access_token)
if not openid:
raise serializers.ValidationError('無效的access_token')
data['openid'] = openid
# 檢驗
mobile = data['mobile']
sms_code = data['sms_code']
redis_conn = get_redis_connection('verify_codes')
real_sms_code = redis_conn.get('sms_%s' % mobile)
if real_sms_code.decode() != sms_code:
raise serializers.ValidationError('錯誤')
# 如果用户存在,檢查用户
try:
user = User.objects.get(mobile=mobile)
except User.DoesNotExist:
pass
else:
password = data['password']
if not user.check_password(password):
raise serializers.ValidationError(' 錯誤')
data['user'] = user
return data
def create(self, validated_data):
user = validated_data.get('user')
if not user:
# 用户不存在
user = User.objects.create_user(
username=validated_data['mobile'],
password=validated_data['password'],
mobile=validated_data['mobile'],
)
OAuthUser.objects.create(
openid=validated_data['openid'],
user=user
)
return user
在oauth/views.py修改AuthUserView 視圖,增加post方法
SQLAlchemy 文檔
PyQt5 文檔
class AuthUserView(GenericAPIView):
"""
登錄的用户
"""
serializer_class = OAuthUserSerializer
def post(self, request):
"""
保存登錄用户數據
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
# 生成已登錄的token
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
response = Response({
'token': token,
'user_id': user.id,
'username': user.username
})
return response
前端
在oauth_back.js中實現
// 保存
on_submit: function(){
this.check_pwd();
this.check_phone();
this.check_sms_code();
if(this.error_password == false && this.error_phone == false && this.error_sms_code == false) {
axios.post(this.host + '/oauth/qq/user/', {
password: this.password,
mobile: this.mobile,
sms_code: this.sms_code,
access_token: this.access_token
}, {
responseType: 'json',
})
.then(response => {
// 記錄用户登錄狀態
sessionStorage.clear();