登錄註冊介面搭建

来源:https://www.cnblogs.com/suncolor/archive/2022/11/03/16853710.html
-Advertisement-
Play Games

登錄介面分析 登錄分為多方式登錄和驗證碼登錄方式 多方式登錄 1)前臺提供賬號密碼,賬號可能是 用戶名、手機號、郵箱等 介面: 後臺只需要提供一個多方式登錄介面即可 - 多方式登錄介面 多方式登錄介面 前端輸入完賬號和密碼,點擊登錄,向後端發送請求進行校驗用戶登錄數據 urls.py from dj ...


登錄介面分析

登錄分為多方式登錄和驗證碼登錄方式

多方式登錄

1)前臺提供賬號密碼,賬號可能是 用戶名、手機號、郵箱等

介面:
後臺只需要提供一個多方式登錄介面即可 - 多方式登錄介面

多方式登錄介面

前端輸入完賬號和密碼,點擊登錄,向後端發送請求進行校驗用戶登錄數據

urls.py

from django.urls import path,re_path,include
from rest_framework.routers import SimpleRouter
from user import views

router = SimpleRouter()
router.register('',views.LoginView,'login')

urlpatterns = [
    path('',include(router.urls)),
]

views.py

from rest_framework.viewsets import ViewSet
from user import serializers
from luffyapi.utils.response import APIResponse
from rest_framework.decorators import action
class LoginView(ViewSet):
    # 密碼方式登錄介面
    @action(methods=['POST'],detail=False) # 加入action裝飾器,自動生成路由
    def login(self,request,*args,**kwargs):
        # 把前端傳入的用戶登錄數據傳入序列化器
        ser = serializers.UserModelserialize(data=request.data)
        # 判讀傳入的數據是否合法
        if ser.is_valid():
            # 合法獲取token和用戶名
            token =ser.context['token']
            username = ser.context['user'].username
            # 然後返回給前端
            return APIResponse(token=token,username=username)
        else:
            return APIResponse(code='0',msg=ser.errors)

serializes.py

from rest_framework import serializers
from user import models
from rest_framework.exceptions import ValidationError


class UserModelserialize(serializers.ModelSerializer):
    username = serializers.CharField() # ?
    class Meta:
        model = models.UserInfo
        fields = ['username','password','id']
        extra_kwargs = {
            'id':{'read_only':True},
            'password': {'write_only': True},
        }

    def validate(self, attrs):
        # 多種方式登錄
        user = self._get_user(attrs)
        # 簽發token
        token = self._get_token(user)
        # 放到context中,我在視圖函數中可以取出來
        self.context['token'] = token
        self.context['user'] = user
        return attrs

    # 校驗前端發來的數據
    def _get_user(self, attrs):
        # 獲取前端發送的數據
        username = attrs.get('username')
        password = attrs.get('password')
        import re
        # 校驗前端的用戶是否為手機號、郵箱、用戶名登錄
        if re.match('^1[3-9][0-9]{9}$',username):
            user = models.UserInfo.objects.filter(telephone=username).first()
        elif re.match('^.+@.+$',username):
            user = models.UserInfo.objects.filter(email=username).first()
        else:
            user = models.UserInfo.objects.filter(username=username).first()
        # 用戶名存在,則校驗密碼
        if user:
            ret = user.check_password(password)
            if ret:
                return user
            else:
                raise ValidationError('密碼錯誤')
        else:
            raise ValidationError('用戶名不存在')

    # 簽發token函數,前面加一個_暗示內部使用的
    def _get_token(self,user):
        from rest_framework_jwt.serializers import jwt_payload_handler,jwt_encode_handler
        pyload = jwt_payload_handler(user) #通過user對象獲取pyload
        token = jwt_encode_handler(pyload) #通過pyload獲取token
        return token

驗證碼登錄

驗證碼可以保存在redis里,也可以保存在緩存里

1)前臺提供手機號和驗證碼完成登錄

介面:
前臺填完手機號,往後臺發送校驗手機號的請求,如果存在繼續,不存在提示註冊 - 手機號存在與否介面
前臺點擊發送驗證碼,將手機再次發送給後臺,後臺將手機號通知給第三方,發送簡訊 - 手機驗證碼介面
前臺點擊登錄提交手機號與驗證碼,完成驗證碼登錄 - 驗證碼登錄介面

手機號是否存在的介面設計

    # 校驗手機號是否存在介面
    @action(methods=['GET'], detail=False)
    def check_telephone(self, request, *args, **kwargs):
        telephone = request.GET.get('telephone')
        if not re.match('^1[3-9][0-9]{9}$',telephone):
            return APIResponse(code=0,msg='手機號不合法')
        try:
            models.UserInfo.objects.get(telephone=telephone)
            return APIResponse()
        except:
            return APIResponse(code=0,msg='手機號不存在')

發送驗證碼介面

from luffyapi.libs.tx_msg import get_code,send_message # 導入封裝好的簡訊介面
from django.core.cache import cache # 導入緩存
from django.conf import settings
    # 發送驗證碼介面
    @action(methods=['GET'], detail=False)
    def send(self,request,*args,**kwargs):
        telephone = request.GET.get('telephone')
        if not re.match('^1[3-9][0-9]{9}$',telephone):
            return APIResponse(code=0,msg='手機號不合法')
        code = get_code() #獲取隨機驗證碼
        result = send_message(telephone,code)
        # 將驗證碼保存到緩存中備用,參數分別是key,value,過期時間秒
        # 這個telephone可以有標識一點,在settings進行配置一下
        cache.set(settings.CACHE_MSG % telephone,code,180)
        # 如果result返回true
        if result:
            return APIResponse(msg='驗證碼發送成功')
        else:
            return APIResponse(code=0,msg='驗證碼發送失敗')

簡訊發送頻率限制

寫一個throttlings.py

from rest_framework.throttling import BaseThrottle, SimpleRateThrottle

# 寫一個類繼承SimpleRateThrottle
class TimeThrottling(SimpleRateThrottle):
    scope = 'sms'
    def get_cache_key(self, request, view):
        telephone = request.query_params.get('telephone')

        return self.cache_format%{'scope':'sms','ident':telephone} # 以手機號返回不太好,換一種不易重名的返回做限制

在settings里配置一下頻率

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'sms': '1/m'  # 一分鐘訪問1次
    }
}

views.py

from . import throttlings
class SendView(ViewSet):
    # 發送簡訊頻率限制
    throttle_classes = [throttlings.TimeThrottling]
    # 發送驗證碼介面
    @action(methods=['GET'], detail=False)
    def send(self,request,*args,**kwargs):
        telephone = request.query_params.get('telephone')
        if not re.match('^1[3-9][0-9]{9}$',telephone):
            return APIResponse(code=0,msg='手機號不合法')
        code = get_code() #獲取隨機驗證碼
        result = send_message(telephone,code)
        # 將驗證碼保存到緩存中備用,參數分別是key,value,過期時間秒
        # 這個telephone可以有標識一點,在settings進行配置一下
        cache.set(settings.CACHE_MSG % telephone,code,180)
        # 如果result返回true
        if result:
            return APIResponse(msg='驗證碼發送成功')
        else:
            return APIResponse(code=0,msg='驗證碼發送失敗')

手機號登陸介面

serializes.py
作用:對前端發來的手機號和驗證碼進行校驗,並簽發token

class UserCodeModelserialize(serializers.ModelSerializer):
    code = serializers.CharField(max_length=4,min_length=4)
    class Meta:
        model = models.UserInfo
        fields = ['telephone','code']

    # 這裡因為手機號驗證碼方式登錄也需要校驗和簽發token,所以也需要重寫validate方法
    def validate(self, attrs):
        user = self._get_user(attrs)
        token = self._get_token(user)
        self.context['user'] = user
        self.context['token'] = token
        return attrs

    def _get_user(self, attrs):
        # 獲取前端發送的數據
        telephone = attrs.get('telephone')
        code = attrs.get('code')
        # 取出生產的code與用戶傳的code做比較
        cache_code = cache.get(settings.CACHE_MSG%telephone)
        if cache_code == code:
            user = models.UserInfo.objects.filter(telephone=telephone).first()
            if user:
                cache.set(settings.CACHE_MSG%telephone,'')
                return user
            else:
                raise ValidationError('用戶不存在')
        else:
            raise ValidationError('驗證碼不正確')


    # 簽發token函數,前面加一個_暗示內部使用的
    def _get_token(self,user):
        from rest_framework_jwt.serializers import jwt_payload_handler,jwt_encode_handler
        pyload = jwt_payload_handler(user) #通過user對象獲取pyload
        token = jwt_encode_handler(pyload) #通過pyload獲取token
        return token

views.py

    # 驗證碼方式登錄介面
    @action(methods=['POST'], detail=False)
    def code_login(self, request, *args, **kwargs):
        # 把前端傳入的用戶登錄數據傳入序列化器
        ser = serializers.UserCodeModelserialize(data=request.data)
        # 判讀傳入的數據是否合法
        if ser.is_valid():
            # 合法獲取token和用戶名
            token = ser.context['token']
            username = ser.context['user'].username
            # 然後返回給前端
            return APIResponse(token=token, username=username)
        else:
            return APIResponse(code='0', msg=ser.errors)

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

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 for in 和 for of 相對於大家肯定都不陌生,都是用來遍歷屬性的沒錯。那麼先看下麵的一個例子: 例1 const obj = { a: 1, b: 2, c: 3 } for (let i in obj) { console.l ...
  • 一、Yarn 產生的背景 Hadoop2 之前是由 HDFS 和 MR 組成的,HDFS 負責存儲,MR 負責計算。 一)MRv1 的問題 耦合度高:MR 中的 jobTracker 同時負責資源管理和作業控制兩個功能,互相制約。 可靠性差:管理節點是單機的,有單點故障的問題。 資源利用率低:基於 ...
  • 面向對象 一、三大特征之繼承 python三大特征: 封裝、繼承、多態 三者中繼承最為核心,實際應用多,感受較為直觀 封裝和多態略微抽象 1、繼承的概念 繼承的含義: ​ 在現實生活中,繼承表示人與人之間資源的從屬關係 ​ 例如:兒子繼承父親 ​ 在編程的世界中,繼承表示類與類之間的資源從屬關係 ​ ...
  • 熱度已經過了,但還是覺得有必要從架構設計的角度來討論一下此事。並用以往我的經驗來設計一套負載能力更好一些的系統。 先說一下基本的架構思路: 最大限度的避免計算,靜態化 不用資料庫,更新類操作使用APPEND模式的文本文件 流程最短,最好是客戶端訪問的第一臺伺服器就能完成全部工作 善用CDN 客戶端負 ...
  • 您好,我是湘王,這是我的博客園,歡迎您來,歡迎您再來~ 從之前的Lambda表達式的演變過程可以知道,Lambda表達式其實是一個對匿名內部類的簡化過程:去掉了多餘的語法修飾,只保留最最核心的部分。在Java中類似這種使用匿名內部類寫代碼的場景非常多,比如Runnable介面,就是典型的最好使用La ...
  • 本節內容會用到之前給大家講過的這兩篇: 2流高手速成記(之六):從SpringBoot到SpringCloudAlibaba 2流高手速成記(之三):SpringBoot整合mybatis/mybatis-plus實現數據持久化 鏈接掛出來,方便咱們中途對比著看 老規矩,先放出本節的項目結構: 我們 ...
  • XML 官方文檔:https://www.w3school.com.cn/xml/index.asp 1.為什麼需要xml? 需求1:兩個程式間進行數據通信? 需求2:給一臺伺服器,做一個配置文件,當伺服器程式啟動時,去讀取它應當監聽的埠號、還有連接資料庫的用戶名和密碼 spring中的IOC配置 ...
  • 大家好,我是metahuber,數字宇宙探索者。 本系列教程是Python的入門教程,本篇文章是此教程的第一篇,希望大家多多關註。 在學習Python之前,我們首先瞭解下什麼是編程語言。 說到編程語言,還需要從程式說起。 其實,程式就是一系列指令,電腦之所以能夠工作,根本的原因是它能夠識別人類發出 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...