まとめ最近、antd pro を使用してプロジェクトを開発しているときに、ユーザー名とパスワードなどの以前のログイン方法を使用する代わりに、ログイン インターフェイスで SMS 検証コードを使用してログインするという新しい要件に遭遇しました。 この方法では SMS 料金が追加されますが、セキュリティが大幅に向上します。Antd にはカウントダウン ボタンが組み込まれていません。 全体的なプロセスSMS 認証コードによるログインのプロセスは非常に簡単です。
フロントエンドページコードReact をインポートし、{useState} を 'react' から取得します。 'umi' から connect をインポートします。 'antd' から { message } をインポートします。 '@ant-design/pro-form' から ProForm、{ ProFormText、ProFormCaptcha } をインポートします。 '@ant-design/icons' から { MobileTwoTone、MailTwoTone } をインポートします。 '@/services/login' から { sendSmsCode } をインポートします。 const ログイン = (props) => { const [countDown, handleCountDown] = useState(5); const { ディスパッチ } = props; const [フォーム] = ProForm.useForm(); 戻る ( <div スタイル={{ 幅: 330, マージン: 'auto'、 }} > <プロフォーム フォーム={フォーム} 提出者={{ 検索設定: { 送信テキスト: 'ログイン', }, レンダリング: (_, dom) => dom.pop(), 送信ボタンプロパティ: { サイズ: 「大」、 スタイル: { 幅: '100%'、 }, }, onSubmit: 非同期() => { const fieldsValue = form.validateFields() を待機します。 console.log(フィールド値); ディスパッチを待つ({ タイプ: 'ログイン/ログイン'、 ペイロード: { ユーザー名: fieldsValue.mobile、 SMS コード: fieldsValue.code }, }); }, }} > <ProFormText フィールドプロパティ={{ サイズ: 「大」、 プレフィックス: <MobileTwoTone />, }} 名前="モバイル" placeholder="電話番号を入力してください" ルール={[ { 必須: true、 メッセージ: 「電話番号を入力してください」 }, { パターン: 新しい正規表現(/^1[3-9]\d{9}$/, 'g'), メッセージ: 「電話番号の形式が正しくありません」 }, ]} /> <ProFormCaptcha フィールドプロパティ={{ サイズ: 「大」、 プレフィックス: <MailTwoTone />, }} countDown={countDown} キャプチャプロパティ={{ サイズ: 「大」、 }} 名前="コード" ルール={[ { 必須: true、 メッセージ: '確認コードを入力してください! '、 }, ]} placeholder="確認コードを入力してください" onGetCaptcha={非同期(モバイル) => { (!form.getFieldValue('モバイル')){ message.error('まず電話番号を入力してください'); 戻る; } m = form.getFieldsError(['mobile']); とします。 (m[0].errors.length > 0)の場合{ メッセージ.エラー(m[0].エラー[0]); 戻る; } 応答を待機します。sendSmsCode(mobile); if (response.code === 10000) message.success('確認コードが正常に送信されました!'); それ以外の場合は、message.error(response.message); }} /> </プロフォーム> </div> ); }; デフォルトの connect()(Login) をエクスポートします。 検証コードとログイン サービスをリクエストする (src/services/login.js)'@/utils/request' からリクエストをインポートします。 非同期関数login(params)をエクスポートします。 リクエストを返します('/api/v1/login', { メソッド: 'POST'、 データ: パラメータ、 }); } 非同期関数 sendSmsCode(mobile) をエクスポートします。 リクエストを返します(`/api/v1/send/smscode/${mobile}`, { メソッド: 'GET'、 }); } ログインを処理するモデル (src/models/login.js)'querystring' から { stringify } をインポートします。 'umi' から { history } をインポートします。 '@/services/login' から { login } をインポートします。 '@/utils/utils' から getPageQuery をインポートします。 'antd' から { message } をインポートします。 'md5' から md5 をインポートします。 定数モデル = { 名前空間: 'ログイン', 状態: ''、 ログインタイプ: ''、 州: { トークン: ''、 }, 効果: *ログイン({ ペイロード }, { 呼び出し、配置 }) { ペイロード.client = 'admin'; // ペイロード.パスワード = md5(ペイロード.パスワード); const response = yield call(ログイン、ペイロード); (レスポンスコード!== 10000)の場合{ メッセージ.エラー(応答.メッセージ); 戻る; } // トークンをローカルストレージに設定する (window.localStorage)の場合{ window.localStorage.setItem('jwt-token', response.data.token); } イールドプット({ タイプ: 'changeLoginStatus'、 ペイロード: { データ: response.data、ステータス: response.status、ログインタイプ: response.loginType }, }); // ログインに成功しました const urlParams = 新しい URL(window.location.href); 定数パラメータ = getPageQuery(); { リダイレクト } = パラメータ; console.log(リダイレクト); if (リダイレクト) { const redirectUrlParams = 新しい URL(リダイレクト); (redirectUrlParams.origin === urlParams.origin)の場合{ リダイレクト = redirect.substr(urlParams.origin.length); リダイレクトマッチ(/^\/.*#/)の場合 リダイレクト = redirect.substr(redirect.indexOf('#') + 1); } } それ以外 { window.location.href = '/home'; } } history.replace(リダイレクト || '/home'); }, ログアウト() { const { redirect } = getPageQuery(); // 注意: セキュリティ上の問題がある可能性がありますので、ご注意ください window.localStorage.removeItem('jwt-token'); if (window.location.pathname !== '/user/login' && !redirect) { 履歴を置き換える({ パス名: '/user/login', 検索: 文字列化({ リダイレクト: window.location.href、 })、 }); } }, }, リデューサー: { changeLoginStatus(状態、{ペイロード}) { 戻る { ...州、 トークン: payload.data.token、 ステータス: ペイロードステータス、 ログインタイプ: ペイロード.ログインタイプ、 }; }, }, }; デフォルトモデルをエクスポートします。 後部バックエンドには主に 2 つのインターフェースがあり、1 つは SMS 検証コードを送信するためのもので、もう 1 つはログイン検証のためのものです。 ルーティング コード スニペット: apiV1.POST("/ログイン", authMiddleware.LoginHandler) apiV1.GET("/send/smscode/:mobile", コントローラー.SendSmsCode) SMS認証コードの処理
次のコードは 6 桁の数字を生成します。乱数が 6 桁未満の場合は、先頭に 0 を追加します。 r := rand.New(rand.NewSource(time.Now().UnixNano())) コード:= fmt.Sprintf("%06v", r.Int31n(1000000)) SMS APIを呼び出す 簡単です。購入したSMSインターフェースの指示に従って呼び出すだけです。 確認のために確認コードを保存してください ここで注意すべき点は、認証コードには有効期限があり、1 つの認証コードを常に使用できるわけではないということです。 パッケージ ユーティリティ 輸入 ( 「fmt」 「数学/ランド」 「同期」 "時間" ) loginItem構造体型{ SMSコード文字列 smsコード有効期限 int64 } LoginMap構造体型{ m map[文字列]*ログイン項目 同期ミューテックス } var lm *ログインマップ InitLoginMap関数(resetTime int64、loginTryMax int) { lm = &ログインマップ{ m: make(map[文字列]*ログイン項目)、 } } func GenSmsCode(キー文字列) 文字列 { r := rand.New(rand.NewSource(time.Now().UnixNano())) コード:= fmt.Sprintf("%06v", r.Int31n(1000000)) _の場合、ok := lm.m[key]; !ok { lm.m[キー] = &ログインアイテム{} } v := lm.m[キー] v.smsCode = コード v.smsCodeExpire = time.Now().Unix() + 600 // 認証コードは10分で期限切れになります return code } func CheckSmsCode(キー、コード文字列) エラー { _の場合、ok := lm.m[key]; !ok { return fmt.Errorf("検証コードは送信されませんでした") } v := lm.m[キー] // 認証コードは期限切れですか? if time.Now().Unix() > v.smsCodeExpire { return fmt.Errorf("検証コード (%s) の有効期限が切れています", code) } // 検証コードは正しいか if code != v.smsCode { return fmt.Errorf("検証コード (%s) が正しくありません", code) } nilを返す } ログイン認証ログイン検証コードは比較的単純で、まず上記の CheckSmsCode メソッドを呼び出して、それが正当かどうかを確認します。 よくある質問Antd バージョンの問題antd pro の ProForm を使用するには、最新バージョンの antd (できれば v4.8 以上) を使用する必要があります。そうでない場合、フロントエンド コンポーネントに互換性のないエラーが発生します。 最適化できるポイント上記の実装は比較的大まかであり、次の側面をさらに最適化できます。 確認コードは、あまり頻繁に送信する必要はありません。結局のところ、SMS メッセージを送信するにはコストがかかります。確認コードはメモリ内に直接保存されるため、システムを再起動すると失われます。redis などのストレージに保存することを検討できます。 antd pro に基づく SMS 認証コード ログイン機能 (プロセス分析) に関するこの記事はこれで終わりです。 antd pro 認証コード ログインに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。 今後とも 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Linux のファイル権限とグループ変更コマンドの詳細な説明
キーコードは次のとおりです。コードをコピーコードは次のとおりです。 html{高さ:100%; }コ...
Ubuntu16.04 のインストールとアンインストール pip実験環境Ubuntu 16.04; ...
目次1. ChildNodes属性のトラバーサル2. 要素シリーズ属性のトラバーサル以前は、chil...
各ブラウザの select タグのプロパティと各ブラウザのサポートが多少異なるため、各ブラウザでの選...
目次Prometheusはエクスポーターを介してMySQLを監視し、Grafanaチャートで表示しま...
始める前に、process.env.NODE_ENV にはデフォルトで開発と本番の 2 つの状態しか...
Baidu には slot-scope に関する記事が既にたくさんありますが、以前よく学習しておら...
位置 / { インデックス index.jsp; proxy_next_upstream http...
この記事では、MySQL での重複キー更新時の replace into と insert into...
リンクに rel="nofollow" 属性を追加すると、検索エンジンにこの接続...
目次1. 概要2. JSON基本ツール3. JSONパス式4. JSONを検索して変更する序文:長い...
selinux ( Security-Enhanced Linux)は、Linux カーネル モジュ...
Nginx は C 言語で開発されており、Linux で実行することをお勧めします。もちろん、Win...
テーブルを美しくするために、行ごとに異なる境界線の色を設定できます。基本的な構文<TR 境界線...
更新: MySQL の公式 Web サイトにアクセスして MySQL インストーラーをインストールし...