まとめ最近、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 のファイル権限とグループ変更コマンドの詳細な説明
reduceメソッドは配列の反復メソッドです。 mapやfilterとは異なり、 reduceメソッ...
今日、SQLトレーニングの質問バンクでこの質問を見ました。これは、非常に代表的なマルチテーブル変更の...
この記事では、例を使用して MySQL コード実行構造について説明します。ご参考までに、詳細は以下の...
書き換えモジュールは ngx_http_rewrite_module モジュールです。その主な機能は...
新しいCSS3プロパティと互換性ありCSS3では、プラグインprefixfree.min.jsを使用...
この記事の例では、参考のためにvueアップロード画像コンポーネントの具体的なコードを共有しています。...
<div align="center"> <table sty...
目次1. DOM の違い2. 同じレイヤーの同じタイプの要素にキー属性を追加する3. キーはインデッ...
パフォーマンスの黄金律:エンドユーザーの応答時間のわずか 10% ~ 20% が HTML ドキュメ...
最近、私は「ぶどうコレクション」というプロジェクトに取り組んでいます。簡単に言うと、Budou ペー...
1. muttをインストールするsudo apt-get install mutt 2. msmtp...
この記事の例では、el-tableを使用して列と行を動的にマージするVueの具体的なコードを参考まで...
cli3 でビルドされた vue プロジェクトは、ゼロ構成ファイルとして知られています。パッケージ化...
CentOS7 64でのMySQL5.6.40のインストール手順1) 以前にインストールしたMySQ...
ハッシュ結合ハッシュ結合は実行にインデックスを必要とせず、ほとんどの場合、現在のブロックネストループ...