ZusammenfassungKürzlich stieß ich bei der Entwicklung eines Projekts mit Antd Pro auf eine neue Anforderung: Die Anmeldung muss über einen SMS-Bestätigungscode auf der Anmeldeoberfläche erfolgen, anstatt die bisherige Anmeldemethode wie Benutzername und Kennwort zu verwenden. Obwohl bei dieser Methode zusätzliche SMS-Gebühren anfallen, verbessert sie die Sicherheit erheblich. Antd verfügt nicht über eine integrierte Countdown-Schaltfläche. GesamtprozessDer Anmeldevorgang per SMS-Bestätigungscode ist ganz einfach:
FrontendSeitencodeimportiere React, { useState } von 'react'; importiere { connect } von „umi“; importiere {Nachricht} von „antd“; importiere ProForm, { ProFormText, ProFormCaptcha } aus '@ant-design/pro-form'; importiere { MobileTwoTone, MailTwoTone } aus '@ant-design/icons'; importiere { sendSmsCode } von '@/services/login'; const Login = (Eigenschaften) => { const [countDown, handleCountDown] = useState(5); const { dispatch } = Requisiten; const [form] = ProForm.useForm(); zurückkehren ( <div Stil={{ Breite: 330, Rand: "auto", }} > <ProForm form={form} Einsender={{ Suchkonfiguration: { submitText: 'Anmelden', }, rendern: (_, dom) => dom.pop(), SubmitButtonProps: { Größe: 'groß', Stil: { Breite: '100%', }, }, beim Senden: async () => { const fieldsValue = warte auf form.validateFields(); console.log(FelderWert); warte auf Versand({ Typ: 'login/login', Nutzlast: { Benutzername: FelderWert.mobile, SMS-Code: FelderWert.code }, }); }, }} > <ProFormText FeldProps={{ Größe: 'groß', Präfix: <MobileTwoTone />, }} Name = "Mobiltelefon" Platzhalter="Bitte geben Sie Ihre Telefonnummer ein" Regeln={[ { erforderlich: wahr, Nachricht: 'Bitte geben Sie Ihre Telefonnummer ein', }, { Muster: neuer RegExp(/^1[3-9]\d{9}$/, 'g'), Meldung: „Das Telefonnummernformat ist falsch“, }, ]} /> <ProFormCaptcha FeldProps={{ Größe: 'groß', Präfix: <MailTwoTone />, }} countDown={countDown} captchaProps={{ Größe: 'groß', }} Name = "Code" Regeln={[ { erforderlich: wahr, Meldung: ,,Bitte geben Sie den Bestätigungscode ein! ', }, ]} Platzhalter="Bitte geben Sie den Bestätigungscode ein" onGetCaptcha={async (mobile) => { wenn (!form.getFieldValue('mobile')) { message.error('Bitte geben Sie zuerst Ihre Telefonnummer ein'); zurückkehren; } let m = form.getFieldsError(['mobile']); wenn (m[0].errors.length > 0) { Nachricht.Fehler(m[0].Fehler[0]); zurückkehren; } let response = warte auf sendSmsCode(mobile); if (response.code === 10000) message.success('Bestätigungscode erfolgreich gesendet!'); sonst Nachricht.Fehler(Antwort.Nachricht); }} /> </ProForm> </div> ); }; exportiere Standard connect()(Anmelden); Bestätigungscode und Login-Dienst anfordern (src/services/login.js)Importiere die Anfrage von „@/utils/request“; exportiere asynchrone Funktion login(params) { Rückgabeanforderung('/api/v1/login', { Methode: 'POST', Daten: Parameter, }); } exportiere asynchrone Funktion sendSmsCode(mobile) { Anfrage zurückgeben(`/api/v1/send/smscode/${mobile}`, { Methode: 'GET', }); } Modell, das die Anmeldung handhabt (src/models/login.js)importiere { stringify } aus 'Abfragezeichenfolge'; importiere { Verlauf } von „umi“; importiere { login } von '@/services/login'; importiere { getPageQuery } aus '@/utils/utils'; importiere {Nachricht} von „antd“; importiere md5 von „md5“; const Modell = { Namespace: "Anmelden", Status: '', Anmeldetyp: '', Zustand: { Token: '', }, Effekte: *login({ Nutzlast }, { aufrufen, setzen }) { Nutzlast.Client = "Administrator"; // Nutzlast.Passwort = md5(Nutzlast.Passwort); const Antwort = Ertragsanruf (Anmeldung, Nutzlast); wenn (Antwortcode !== 10000) { Nachricht.Fehler(Antwort.Nachricht); zurückkehren; } // Token im lokalen Speicher festlegen wenn (window.localStorage) { window.localStorage.setItem('jwt-token', response.data.token); } Rendite setzen({ Typ: 'changeLoginStatus', Nutzlast: {Daten: Antwort.Daten, Status: Antwort.Status, Anmeldetyp: Antwort.Anmeldetyp}, }); // Anmeldung erfolgreich const urlParams = neue URL(window.location.href); const params = getPageQuery(); let { umleiten } = Parameter; console.log(Umleitung); wenn (Umleitung) { const redirectUrlParams = neue URL(Umleitung); wenn (redirectUrlParams.origin === urlParams.origin) { Umleitung = Umleitung.substr(urlParams.origin.length); wenn (redirect.match(/^\/.*#/)) { Umleitung = Umleitung.substr(Umleitung.indexOf('#') + 1); } } anders { Fenster.Standort.href = "/home"; } } Verlauf.Ersetzen(Umleitung || '/home'); }, abmelden() { const { redirect } = getPageQuery(); // Hinweis: Es können Sicherheitsprobleme auftreten. Bitte beachten Sie window.localStorage.removeItem('jwt-token'); wenn (Fenster.Standort.Pfadname !== '/Benutzer/Anmeldung' && !Umleitung) { Verlauf.ersetzen({ Pfadname: '/user/login', Suche: stringify({ Umleitung: window.location.href, }), }); } }, }, Reduzierstücke: { changeLoginStatus(status, { nutzlast }) { zurückkehren { ...Zustand, Token: Nutzlast.Daten.Token, Status: Nutzlast.Status, Anmeldetyp: payload.Anmeldetyp, }; }, }, }; Standardmodell exportieren; hinteres EndeDas Backend verfügt im Wesentlichen über zwei Schnittstellen, eine zum Versenden von SMS-Bestätigungscodes und eine zur Login-Bestätigung. Routing-Code-Ausschnitt: apiV1.POST("/login", authMiddleware.LoginHandler) apiV1.GET("/send/smscode/:mobile", controller.SendSmsCode) Verarbeitung des SMS-Bestätigungscodes
Der folgende Code generiert eine 6-stellige Zahl. Wenn die Zufallszahl weniger als 6 Ziffern hat, fügen Sie davor eine 0 hinzu. r := rand.Neu(rand.NeueQuelle(Zeit.Jetzt().UnixNano())) Code := fmt.Sprintf("%06v", r.Int31n(1000000)) SMS-API anrufen Dies ist ganz einfach. Rufen Sie es einfach gemäß der Anleitung der erworbenen SMS-Schnittstelle auf. Prüfcode zur Verifizierung speichern Hierbei ist zu beachten, dass der Verifizierungscode ein Ablaufdatum haben muss und ein Verifizierungscode nicht immer wieder verwendet werden kann. Paket-Dienstprogramm importieren ( "fmt" "Mathematik/Rand" "Synchronisieren" "Zeit" ) Typ loginItem-Struktur { smsCode-Zeichenfolge smsCodeExpire int64 } Typ LoginMap-Struktur { m Karte [Zeichenfolge] * LoginItem synchronisieren.Mutex } var lm *LoginMap Funktion InitLoginMap(resetTime int64, loginTryMax int) { lm = &LoginMap{ m: make(map[string]*loginItem), } } func GenSmsCode(Schlüsselzeichenfolge) Zeichenfolge { r := rand.Neu(rand.NeueQuelle(Zeit.Jetzt().UnixNano())) Code := fmt.Sprintf("%06v", r.Int31n(1000000)) wenn _, ok := lm.m[Schlüssel]; !ok { lm.m[Schlüssel] = &loginItem{} } v := lm.m[Schlüssel] v.smsCode = Code v.smsCodeExpire = time.Now().Unix() + 600 // Der Bestätigungscode läuft in 10 Minuten ab Rückgabecode } func CheckSmsCode(Schlüssel, Code-String) Fehler { wenn _, ok := lm.m[Schlüssel]; !ok { return fmt.Errorf("Bestätigungscode nicht gesendet") } v := lm.m[Schlüssel] // Ist der Bestätigungscode abgelaufen? if time.Now().Unix() > v.smsCodeExpire { return fmt.Errorf("Verifizierungscode (%s) ist abgelaufen", Code) } // Ist der Bestätigungscode korrekt, wenn Code != v.smsCode { return fmt.Errorf("Verifizierungscode (%s) falsch", Code) } Rückgabe Null } Anmeldeüberprüfung Der Anmeldebestätigungscode ist relativ einfach: Rufen Sie zuerst die oben genannte Methode CheckSmsCode auf, um zu überprüfen, ob er zulässig ist. Häufig gestellte FragenAntd-VersionsproblemUm ProForm von Antd Pro zu verwenden, müssen Sie die neueste Version von Antd verwenden, vorzugsweise >= v4.8, da sonst Inkompatibilitätsfehler in den Front-End-Komponenten auftreten. Optimierbare PunkteDie obige Implementierung ist relativ grob und die folgenden Aspekte können weiter optimiert werden: Der Bestätigungscode muss seltener gesendet werden. Schließlich kostet das Senden von SMS-Nachrichten Geld. Der Bestätigungscode befindet sich direkt im Speicher und geht nach dem Neustart des Systems verloren. Sie können erwägen, ihn in einem Speicher wie Redis abzulegen. Dies ist das Ende dieses Artikels über die SMS-Bestätigungscode-Anmeldefunktion (Prozessanalyse) basierend auf Antd Pro. Weitere relevante Antd Pro-Bestätigungscode-Anmeldeinhalte finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Detaillierte Erläuterung der Linux-Dateiberechtigungen und Befehle zur Gruppenänderung
>>: So verbinden Sie JDBC mit MySQL 5.7
1. Melden Sie sich bei MySQL an: mysql -u root -h...
ElementUI implementiert das Tutorial zum Paginier...
In diesem Artikelbeispiel wird der spezifische Co...
1. Installieren Sie zuerst die Pagode Installatio...
Ich habe bereits einige Nachforschungen zum Thema...
Ich habe mich kürzlich mit Linux beschäftigt und ...
Inhaltsverzeichnis eins. Umfeld zwei. Vorsichtsma...
„explain“ wird verwendet, um Informationen zum Ab...
Vorwort In diesem Artikel erfahren Sie hauptsächl...
Private Docker-Imagebibliothek Private Docker-Bil...
Wenn wir einmal von Datenbanken absehen, was ist ...
1. Entpacken Sie das Zip-Paket in das Installatio...
1. Befehlseinführung Mit „time“ werden die für di...
Docker Compose Einführung in Compose Compose ist ...
In diesem Artikelbeispiel wird der spezifische Ja...