(項目)生鮮超市(六)

来源:https://www.cnblogs.com/Sweltering/archive/2018/11/26/10017611.html
-Advertisement-
Play Games

七、用戶登錄與手機註冊 1、drf的token 在INSTALLED_APPS中註冊: 然後遷移資料庫,會生成一張表authtoken_token,存放用戶的token信息: 配置token的url: 然後現在測試發起post請求登錄,我們使用postman工具來發起請求: drf返回的token值 ...


七、用戶登錄與手機註冊

1、drf的token

  在INSTALLED_APPS中註冊:

1 INSTALLED_APPS = (
2     'rest_framework.authtoken'
3 )

  然後遷移資料庫,會生成一張表authtoken_token,存放用戶的token信息:

  配置token的url:

1 from rest_framework.authtoken import views
2 
3 
4 urlpatterns = [
5     path('api-token-auth/', views.obtain_auth_token),  # drf-token
6 ]

  然後現在測試發起post請求登錄,我們使用postman工具來發起請求:

  drf返回的token值會保存到資料庫中並與用戶進行關聯:

  然後客戶端需要進行身份驗證,令牌密鑰包含在 Authorization HTTP header 中。關鍵字應以字元串文字 “Token” 為首碼,用空格分隔兩個字元串。例如:

Authorization: Token 30fc1a3cab2d97a6ab3431d603a0bfc40145785b

  通過驗證TokenAuthentication 將提供以下憑據:

  • request.user
  • request.auth

  要想獲取這兩個實例,還要在settings.py中添加以下設置:

1 REST_FRAMEWORK = {
2     'DEFAULT_AUTHENTICATION_CLASSES': (
3         'rest_framework.authentication.BasicAuthentication',
4         'rest_framework.authentication.SessionAuthentication',
5         'rest_framework.authentication.TokenAuthentication'
6     )
7 }

  drf的token也有很大的缺點:

  • token信息是保存在資料庫中的,如果是一個分散式的系統,就比較麻煩
  • token永久有效,沒有過期時間

2、json web token方式完成用戶認證(JWT)

  在虛擬環境中pip install djangorestframework-jwt

  將settings中的REST_FRAMEWORK的TokenAuthentication改成JSONWebTokenAuthentication:

1 REST_FRAMEWORK = {
2     'DEFAULT_AUTHENTICATION_CLASSES': (
3         'rest_framework.authentication.BasicAuthentication',
4         'rest_framework.authentication.SessionAuthentication',
5         # 'rest_framework.authentication.TokenAuthentication'
6         'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
7     )
8 }

  然後修改jwt的url:

1 from rest_framework_jwt.views import obtain_jwt_token
2 
3 urlpatterns = [
4     path('jwt-auth/', obtain_jwt_token )
5 ]

  通過postman發起請求:

3、Vue和JWT介面調試

  vue中登錄介面是login:

1 //登錄
2 export const login = params => {
3   return axios.post(`${host}/login/`, params)
4 }

  後臺的介面要與前端保持一致:

1 urlpatterns = [
2     path('login/', obtain_jwt_token ),  # jwt-token
3 ]

  jwt介面預設採用的是用戶名和密碼登錄驗證,如果用手機登錄的話,就會驗證失敗,所以我們需要自定義一個用戶驗證,在users/view.py中編寫:

 1 from django.shortcuts import render
 2 from django.contrib.auth.backends import ModelBackend
 3 from django.contrib.auth import get_user_model
 4 from django.db.models import Q
 5 
 6 # Create your views here.
 7 
 8 
 9 User = get_user_model()
10 
11 
12 class CustomBackend(ModelBackend):
13     """jwt自定義用戶驗證"""
14 
15     def authenticate(self, request, username=None, password=None, **kwargs):
16         try:
17             user = User.objects.get(Q(username=username) | Q(mobile=username))
18             if user.check_password(password):
19                 return user
20         except Exception as e:
21             return None

  然後在setting中配置定義好的類:

1 AUTHENTICATION_BACKENDS = (
2     'users.views.CustomBackend',
3 )

  jwt過期時間的設置,在setting中配置:

# jwt過期時間
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),  # 也可以設置seconds=20
    'JWT_AUTH_HEADER_PREFIX': 'JWT',  # JWT跟前端保持一致,比如“token”這裡設置成JWT
}

4、雲片網發送簡訊驗證碼

  在雲片網進行註冊,完善開發者信息,然後新增簽名和模板,審核通過之後,添加ip白名單,測試的時候使用本地ip,線上部署的時候一定要換成伺服器的ip。

  然後編寫發送驗證碼的邏輯,在apps下新建utils文件夾,新建yunpian.py文件:

 1 import requests
 2 import json
 3 
 4 
 5 class YunPian(object):
 6     def __init__(self, api_key):
 7         self.api_key = api_key
 8         self.single_send_url = 'https://sms.yunpian.com/v2/sms/single_send.json'
 9 
10     def send_sms(self, code, mobile):
11         # 向雲片網發起請求的參數
12         parmas = {
13             "apikey": self.api_key,
14             "mobile": mobile,
15             "text": "【倍思樂】您的驗證碼是{code}。如非本人操作,請忽略本簡訊".format(code=code)
16         }
17 
18         # 發起請求
19         response = requests.post(self, self.single_send_url, data=parmas)
20         re_dict = json.loads(response.text)
21         return re_dict
22 
23 
24 # 測試
25 if __name__ == '__main__':
26     yun_pian = YunPian('9b11127a9701975c734b8aee81ee3526')
27     yun_pian.send_sms('2018', '13993601652')

  現在開始編寫發送簡訊驗證碼的介面,首先在settings中配置手機號碼的正則表達式:

1 # 手機號碼正則表達式
2 REGEX_MOBILE = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$"

  然後對手機號碼進行序列化,在users下新建serializers.py:

 1 import re
 2 from datetime import datetime, timedelta
 3 
 4 from rest_framework import serializers
 5 from django.contrib.auth import get_user_model
 6 
 7 from MxShop.settings import REGEX_MOBILE
 8 from .models import VerifyCode
 9 
10 User = get_user_model()
11 
12 
13 class SmsSerializer(serializers.Serializer):
14     mobile = serializers.CharField(max_length=11)
15 
16     # 函數名必須是validate + 驗證的欄位名
17     def validate_mobile(self, mobile):
18         """手機號驗證"""
19 
20         # 查詢手機號是否已註冊
21         if User.objects.filter(mobile=mobile).count():
22             raise serializers.ValidationError('用戶已存在')
23 
24         # 驗證手機號碼是否合法
25         if not re.match(REGEX_MOBILE, mobile):
26             raise serializers.ValidationError('手機號碼非法')
27 
28         # 限制驗證碼的發送頻率,60秒發送一次
29         one_mintes_ago = datetime.now() - timedelta(hours=0, minutes=1, seconds=0)
30         if VerifyCode.objects.filter(add_time__gt=one_mintes_ago, mobile=mobile).count():
31             raise serializers.ValidationError('距離上一次發送未超過60秒')
32 
33         return mobile

  將雲片網的apikey配置到settings中:

1 # 雲片網的apikey
2 APIKEY = "xxxxx327d4be01608xxxxxxxxxx"

  現在開始完善發送簡訊驗證碼的介面:

 1 class SmsCodeViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
 2     """手機驗證碼"""
 3 
 4     serializer_class = SmsSerializer
 5 
 6     # 隨機生成code
 7     def generate_code(self):
 8         seeds = "1234567890"
 9         random_str = []
10         for i in range(4):
11             random_str.append(choice(seeds))
12 
13         return "".join(random_str)
14 
15     # 重寫CreateModelMixin的create方法,加入發送驗證碼的邏輯
16     def create(self, request, *args, **kwargs):
17         # 驗證手機號碼
18         serializer = self.get_serializer(data=request.data)
19         serializer.is_valid(raise_exception=True)
20 
21         # 發送驗證碼
22         mobile = serializer.validated_data["mobile"]
23         yun_pian = YunPian(APIKEY)
24         code = self.generate_code()
25         sms_status = yun_pian.send_sms(code=code, mobile=mobile)
26         if sms_status["code"] != 0:  # 發送失敗
27             return Response({
28                 "mobile": sms_status["msg"]
29             }, status=status.HTTP_400_BAD_REQUEST)
30         else:
31             code_record = VerifyCode(code=code, mobile=mobile)
32             code_record.save()
33             return Response({
34                 "mobile": mobile
35             }, status=status.HTTP_201_CREATED)

  然後註冊url:

1 router.register(r'code', SmsCodeViewSet, base_name='code')  # 簡訊驗證碼

  現在開是在介面中進行驗證,輸入不合法的手機號:

  輸入合法的手機號後,會發送簡訊驗證碼到你的手機。

5、註冊介面編寫

  在編寫註冊介面之前,需要修改UserProfile中的mobile欄位為可以為空,因為前端只有一個值,是username,所以mobile可以為空:

 1 class UserProfile(AbstractUser):
 2     """用戶信息"""
 3 
 4     GENDER_CHOICES = (
 5         ("male", u""),
 6         ("female", u"")
 7     )
 8     name = models.CharField("姓名", max_length=30, null=True, blank=True)
 9     birthday = models.DateField("出生年月", null=True, blank=True)
10     gender = models.CharField("性別", max_length=6, choices=GENDER_CHOICES, default="female")
11     mobile = models.CharField("電話", max_length=11, null=True, blank=True)
12     email = models.EmailField("郵箱", max_length=100, null=True, blank=True)
13 
14     class Meta:
15         verbose_name = "用戶信息"
16         verbose_name_plural = verbose_name
17 
18     def __str__(self):
19         return self.username

  然後編寫用戶註冊的serializer:

 1 class UserRegSerializer(serializers.ModelSerializer):
 2     # UserProfile中沒有code欄位,這裡需要自定義一個code序列化欄位
 3     code = serializers.CharField(required=True, write_only=True, max_length=4, min_length=4,
 4                                  error_messages={
 5                                      "blank": "請輸入驗證碼",
 6                                      "required": "請輸入驗證碼",
 7                                      "max_length": "驗證碼格式錯誤",
 8                                      "min_length": "驗證碼格式錯誤"
 9                                  },
10                                  help_text="驗證碼")
11     # 驗證用戶名是否存在
12     username = serializers.CharField(label="用戶名", help_text="用戶名", required=True, allow_blank=False,
13                                      validators=[UniqueValidator(queryset=User.objects.all(), message="用戶已經存在")])
14 
15     # 驗證code
16     def validate_code(self, code):
17         # 用戶註冊,post方式提交註冊信息,post的數據都保存在initial_data裡面
18         # username就是用戶註冊的手機號,驗證碼按添加時間倒序排序,為了後面驗證過期,錯誤等
19         verify_records = VerifyCode.objects.filter(mobile=self.initial_data["username"]).order_by("-add_time")
20 
21         if verify_records:
22             # 最近的一個驗證碼
23             last_record = verify_records[0]
24             # 有效期為五分鐘
25             five_mintes_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)
26             if five_mintes_ago > last_record.add_time:
27                 raise serializers.ValidationError("驗證碼過期")
28 
29             if last_record.code != code:
30                 raise serializers.ValidationError("驗證碼錯誤")
31 
32         else:
33             raise serializers.ValidationError("驗證碼錯誤")
34 
35     # 所有欄位。attrs是欄位驗證合法之後返回的總的dict
36     def validate(self, attrs):
37         # 前端沒有傳mobile值到後端,這裡添加進來
38         attrs["mobile"] = attrs["username"]
39         # code是自己添加得,資料庫中並沒有這個欄位,驗證完就刪除掉
40         del attrs["code"]
41         return attrs
42 
43     class Meta:
44         model = User
45         fields = ('username', 'code', 'mobile')

  然後在views.py中編寫用戶註冊的介面:

1 class UserViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
2     """用戶註冊"""
3 
4     serializer_class = UserRegSerializer

  註冊url:

1 router.register(r'users', UserViewSet, base_name='users')  # 用戶註冊

  然後在介面中進行測試:

6、django信號量實現用戶密碼修改

  完善用戶註冊介面:

1 class UserViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
2     """用戶註冊"""
3 
4     serializer_class = UserRegSerializer
5     queryset = User.objects.all()

  然後在serializers.py中添加密碼欄位:

1 fields = ('username', 'code', 'mobile', 'password')

  需要註意的是密碼不能明文顯示,需要加密保存, 這是重載Create方法:

 1 class UserRegSerializer(serializers.ModelSerializer):
 2     # UserProfile中沒有code欄位,這裡需要自定義一個code序列化欄位
 3     code = serializers.CharField(required=True, write_only=True, max_length=4, min_length=4,
 4                                  error_messages={
 5                                      "blank": "請輸入驗證碼",
 6                                      "required": "請輸入驗證碼",
 7                                      "max_length": "驗證碼格式錯誤",
 8                                      "min_length": "驗證碼格式錯誤"
 9                                  },
10                                  help_text="驗證碼")
11     # 驗證用戶名是否存在
12     username = serializers.CharField(label="用戶名", help_text="用戶名", required=True, allow_blank=False,
13                                      validators=[UniqueValidator(queryset=User.objects.all(), message="用戶已經存在")])
14 
15     # 輸入密碼的時候不顯示明文
16     password = serializers.CharField(
17         style={'input_type': 'password'}, label=True, write_only=True
18     )
19 
20     # 密碼加密保存
21     def create(self, validated_data):
22         user = super(UserRegSerializer, self).create(validated_data=validated_data)
23         user.set_password(validated_data["password"])
24         user.save()
25         return user
26 
27     # 驗證code
28     def validate_code(self, code):
29         # 用戶註冊,post方式提交註冊信息,post的數據都保存在initial_data裡面
30         # username就是用戶註冊的手機號,驗證碼按添加時間倒序排序,為了後面驗證過期,錯誤等
31         verify_records = VerifyCode.objects.filter(mobile=self.initial_data["username"]).order_by("-add_time")
32 
33         if verify_records:
34             # 最近的一個驗證碼
35             last_record = verify_records[0]
36             # 有效期為五分鐘
37             five_mintes_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)
38             if five_mintes_ago > last_record.add_time:
39                 raise serializers.ValidationError("驗證碼過期")
40 
41             if last_record.code != code:
42                 raise serializers.ValidationError("驗證碼錯誤")
43 
44         else:
45             raise serializers.ValidationError("驗證碼錯誤")
46 
47     # 所有欄位。attrs是欄位驗證合法之後返回的總的dict
48     def validate(self, attrs):
49         # 前端沒有傳mobile值到後端,這裡添加進來
50         attrs["mobile"] = attrs["username"]
51         # code是自己添加得,資料庫中並沒有這個欄位,驗證完就刪除掉
52         del attrs["code"]
53         return attrs
54 
55     class Meta:
56         model = User
57         fields = ('username', 'code', 'mobile', 'password')

  下麵通過信號量的方式來保存密碼,在users下新建signals.py文件:

 1 from django.dispatch import receiver
 2 from django.db.models.signals import post_save
 3 from django.contrib.auth import get_user_model
 4 
 5 
 6 User = get_user_model()
 7 
 8 
 9 # post_save接收信號的方法, sender接收信號的model
10 @receiver(post_save, sender=User)
11 def create_user(sender, instance=None, created=False, **kwargs):
12     # 是否新建,因為update的時候也會進行post_save
13     if created:
14         # instance相當於user
15         password = instance.password
16         instance.set_password(password)
17         instance.save()

  然後在users/apps.py中重載配置:

1 from django.apps import AppConfig
2 
3 
4 class UsersConfig(AppConfig):
5     name = 'users'
6     verbose_name = "用戶管理"
7 
8     def ready(self):
9         import users.signals

  AppConfig自定義的函數,會在django啟動時被運行,現在添加用戶的時候,密碼就會自動加密存儲了。

7、Vue和註冊介面聯調

  完善註冊介面:

 1 class UserViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
 2     """用戶註冊"""
 3 
 4     serializer_class = UserRegSerializer
 5     queryset = User.objects.all()
 6 
 7     def create(self, request, *args, **kwargs):
 8         serializer = self.get_serializer(data=request.data)
 9         serializer.is_valid(raise_exception=True)
10 
11         user = self.perform_create(serializer)
12         re_dict = serializer.data
13         payload = jwt_payload_handler(user)
14         re_dict["token"] = jwt_encode_handler(payload)
15         re_dict["name"] = user.name if user.name else user.username
16 
17         headers = self.get_success_headers(serializer.data)
18         return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)
19 
20     def perform_create(self, serializer):
21         return serializer.save()

  然後將Vue中register的介面的host修改:

1 //註冊
2 
3 export const register = parmas => { return axios.post(`${host}/users/`, parmas) }

  然後在註冊頁面進行測試,發送簡訊註冊成功跳轉到首頁:

  如果沒有在雲片網審核通過的童靴想要測試介面是否正確,可以先暫時修改發送簡訊的介面,將隨機生成的驗證碼列印出來,暫時不同雲片網發送簡訊,修改發送簡訊的介面:

 1 class SmsCodeViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
 2     """手機驗證碼"""
 3 
 4     serializer_class = SmsSerializer
 5 
 6     # 隨機生成code
 7     def generate_code(self):
 8         seeds = "1234567890"
 9         random_str = []
10         for i in range(4):
11             random_str.append(choice(seeds))
12 
13         print("".join(random_str))
14 
15         return "".join(random_str)
16 
17     # 重寫CreateModelMixin的create方法,加入發送驗證碼的邏輯
18     # def create(self, request, *args, **kwargs):
19     #     # 驗證手機號碼
20     #     serializer = self.get_serializer(data=request.data)
21     #     serializer.is_valid(raise_exception=True)
22     #
23     #     # 發送驗證碼
24     #     mobile = serializer.validated_data["mobile"]
25     #     yun_pian = YunPian(APIKEY)
26     #     code = self.generate_code()
27     #     sms_status = yun_pian.send_sms(code=code, mobile=mobile)
28     #     if sms_status["code"] != 0:  # 發送失敗
29     #         return Response({
30     #             "mobile": sms_status["msg"]
31     #         }, status=status.HTTP_400_BAD_REQUEST)
32     #     else:
33     #         code_record = VerifyCode(code=code, mobile=mobile)
34     #         code_record.save()
35     #         return Response({
36     #             "mobile": mobile
37     #         }, status=status.HTTP_201_CREATED)
38 
39     # 以下為沒有使用雲片網
40     def create(self, request, *args, **kwargs):

              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.重新索引 如果reindex會根據新索引重新排序,不存在的則引入預設: In [3]: obj = Series([4.5,7.2,-5.3,3.6], index=["d","b","a","c"]) In [4]: obj Out[4]: d 4.5 b 7.2 a -5.3 c 3.6 d ...
  • 本篇和大家分享的是通過maven對springboot中打war包和jar包;war通常來說生成後直接放到tomcat的webapps下麵就行,tomcat配置自動解壓war,而jar一般通過命令行部署和啟動; 首先,來實戰怎麼生成war包,主要來說可以分為3個步驟: 程式入口改造 排除spring ...
  • 前言 青島的房價這兩年翻了一番,舉個慄子,如果你在2016年在市區買了100萬的房子,2018年價值200萬,凈增100萬;如果你2016年沒有買這100萬的房子,2018年買房將多付100萬,機會成本100萬。而這100萬可能是青島白領不吃不喝十年的收入。 自2018年第二季度起,限價限購限售與金 ...
  • 這次實驗共計7道題目 以下代碼親測無誤 1.用選擇排序法,鍵盤輸入10個整數,對10個整數進行排序(升序) 1.第一種思路就是常規思路,輸入--排序--輸出 源代碼如下: 2.第二種思路就是 我嫌最後一步又用個for迴圈輸出麻煩,想著就是在排序的時候,就給輸出出來 於是乎有了 輸入--排序+輸出 這 ...
  • Django的filter查詢 name__contains表示精確大小寫的模糊查詢 使用name__icontains表示忽略大小寫 ...
  • 讓用戶輸入用戶名密碼 認證成功後顯示歡迎信息 輸錯三次後退出程式 ...
  • urllib提供的功能就是利用程式去執行各種HTTP請求。如果要模擬瀏覽器完成特定功能,需要把請求偽裝成瀏覽器。偽裝的方法是先監控瀏覽器發出的請求,再根據瀏覽器的請求頭來偽裝,User-Agent頭就是用來標識瀏覽器的。 ...
  • 1.setnx鎖在redis中最簡單的數據結構就是string。最早的時候,上鎖的操作一般使用setnx,這個命令是當:lock不存在的時候set一個val,或許你還會記得使用expire來增加鎖的過期,解鎖操作就是使用del命令,偽代碼如下:if (Redis::setnx("my:lock", ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...