Cách xây dựng công cụ đo độ mạnh mật khẩu trong React
Mật khẩu thường được sử dụng để xác thực user trong hầu hết các ứng dụng web. Do đó, điều quan trọng là password phải được lưu trữ theo cách an toàn. Trong nhiều năm, các kỹ thuật như băm password một chiều đã được sử dụng để che giấu biểu diễn thực của password được lưu trữ trong database .Mặc dù băm password là một bước tiến tuyệt vời để bảo mật password , user vẫn đặt ra một thách thức lớn đối với bảo mật password : user sử dụng một từ phổ biến làm password khiến nỗ lực băm không có kết quả, vì một cuộc tấn công brute-force có thể nhanh chóng bẻ khóa password như vậy. .
Để giải quyết vấn đề này, nhiều ứng dụng web ngày nay yêu cầu user phải có password mạnh, bằng cách đảm bảo độ dài password tối thiểu hoặc một số kết hợp của các ký tự chữ và số và ký hiệu trong password . Để đo độ mạnh của password , Dropbox đã phát triển một thuật toán cho một công cụ ước tính độ mạnh password thực tế được lấy cảm hứng từ những người bẻ khóa password . Thuật toán này được đóng gói trong một thư viện JavaScript có tên là zxcvbn
. Ngoài ra, gói còn chứa một từ điển các từ, tên và password tiếng Anh thường được sử dụng.
Trong hướng dẫn này, ta sẽ tạo một biểu mẫu với các trường cho họ tên, email và password bằng cách sử dụng khung React JavaScript. Ta sẽ thực hiện một số xác thực biểu mẫu nhẹ và cũng sử dụng thư viện zxcvbn
để ước tính độ mạnh của password trong biểu mẫu đồng thời cung cấp phản hồi trực quan.
Hãy xem bản demo CodeSandbox này về những gì bạn sẽ tạo ở cuối hướng dẫn này.
Yêu cầu
Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt version Node gần đây trên hệ thống của bạn .
Để làm theo hướng dẫn này, bạn cần những thứ sau:
- Phiên bản gần đây của Node được cài đặt trên máy của bạn. Để biết thêm thông tin về cách cài đặt, hãy chọn bản phân phối của bạn từ bộ sưu tập Cách Cài đặt Node.js.
-
yarn
cài đặt để chạy tất cả các bạn NPM kịch bản và để cài đặt phụ thuộc cho dự án. Bạn có thể làm theo hướng dẫn cài đặt Sợi này để cài đặtyarn
vào hệ thống của bạn .
Bước 1 - Cài đặt ứng dụng
Hướng dẫn này sẽ sử create-react-app
gói create-react-app
để tạo ứng dụng React mới của bạn. Chạy lệnh sau để cài đặt create-react-app
trên hệ thống của bạn nếu bạn chưa cài đặt nó:
- npm install -g create-react-app
Sau khi cài đặt xong, hãy khởi động ứng dụng React mới bằng lệnh sau:
- create-react-app react-password-strength
Lệnh này đặt tên cho nó là react-password-strength
, nhưng bạn có thể đặt tên cho nó bạn muốn .
Lưu ý: Nếu bạn đang sử dụng npm
version 5.2 trở lên, nó được cung cấp với một npx
binary npx
bổ sung. Sử dụng binary npx
, bạn không cần phải cài đặt create-react-app
global trên hệ thống của bạn . Bạn có thể bắt đầu một ứng dụng React mới bằng lệnh sau: npx create-react-app react-password-strength
.
Tiếp theo, bạn sẽ cài đặt các phụ thuộc cần thiết cho ứng dụng. Chạy lệnh sau để cài đặt các phụ thuộc :
- yarn add zxcvbn isemail prop-types node-sass bootstrap
Lệnh này cài đặt các phụ thuộc sau:
-
zxcvbn
- Thư viện ước tính độ mạnh của password đã nói ở trên. -
isemail
- Thư viện xác thực e-mail. -
prop-types
- Kiểm tra thời gian chạy của các loại thuộc tính dự kiến được chuyển đến các thành phần. -
node-sass
- Được sử dụng để biên dịch các file Sass thành CSS.
Như bạn có thể nhận thấy, bạn đã cài đặt gói bootstrap
làm phụ thuộc để ứng dụng có được một số kiểu mặc định. Để bao gồm Bootstrap trong ứng dụng, hãy chỉnh sửa file src/index.js
và thêm dòng sau trước mọi câu lệnh import
khác:
import 'bootstrap/dist/css/bootstrap.min.css';
Cuối cùng, khởi động ứng dụng của bạn:
- yarn start
Ứng dụng hiện đã được bắt đầu và quá trình phát triển có thể bắt đầu. Lưu ý một tab trình duyệt đã được mở cho bạn với chức năng reload trực tiếp . Điều này sẽ tiếp tục đồng bộ với các thay đổi trong ứng dụng khi bạn phát triển.
Đến đây, chế độ xem ứng dụng của bạn sẽ giống như ảnh chụp màn hình sau:
Bước 2 - Xây dựng các thành phần
Ứng dụng này sẽ sử dụng một biểu mẫu cho họ tên, email và password . Nó cũng sẽ thực hiện một số xác nhận dạng nhẹ trên các trường. Trong bước này, bạn sẽ tạo các thành phần React sau:
FormField
-FormField
một trường nhập biểu mẫu với các thuộc tính của nó và trình xử lý sự kiện thay đổi.EmailField
- GóiFormField
email và thêm logic xác thực email vào nó.PasswordField
-FormField
passwordFormField
và thêm logic xác thực password vào đó. Đồng thời gắn đồng hồ đo độ mạnh password và một số dấu hiệu trực quan khác vào hiện trường.JoinForm
- Biểu mẫu Group Hỗ trợ Tham gia hư cấu chứa các trường biểu mẫu.
Tạo một folder components
bên trong folder src
của ứng dụng để chứa tất cả các thành phần.
Thành phần FormField
Tạo một file mới FormField.js
trong folder src/components
và thêm đoạn mã sau vào đó:
import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; class FormField extends Component { // initialize state state = { value: '', dirty: false, errors: [] } hasChanged = e => { e.preventDefault(); // destructure props - assign default dummy functions to validator and onStateChanged props const { label, required = false, validator = f => f, onStateChanged = f => f } = this.props; const value = e.target.value; const isEmpty = value.length === 0; const requiredMissing = this.state.dirty && required && isEmpty; let errors = []; if (requiredMissing) { // if required and is empty, add required error to state errors = [ ...errors, `${label} is required` ]; } else if ('function' === typeof validator) { try { validator(value); } catch (e) { // if validator throws error, add validation error to state errors = [ ...errors, e.message ]; } } // update state and call the onStateChanged callback fn after the update // dirty is only changed to true and remains true on and after the first state update this.setState(({ dirty = false }) => ({ value, errors, dirty: !dirty || dirty }), () => onStateChanged(this.state)); } render() { const { value, dirty, errors } = this.state; const { type, label, fieldId, placeholder, children } = this.props; const hasErrors = errors.length > 0; const controlClass = ['form-control', dirty ? hasErrors ? 'is-invalid' : 'is-valid' : '' ].join(' ').trim(); return ( <Fragment> <div className="form-group px-3 pb-2"> <div className="d-flex flex-row justify-content-between align-items-center"> <label htmlFor={fieldId} className="control-label">{label}</label> {/** Render the first error if there are any errors **/} { hasErrors && <div className="error form-hint font-weight-bold text-right m-0 mb-2">{ errors[0] }</div> } </div> {/** Render the children nodes passed to component **/} {children} <input type={type} className={controlClass} id={fieldId} placeholder={placeholder} value={value} onChange={this.hasChanged} /> </div> </Fragment> ); } } FormField.propTypes = { type: PropTypes.oneOf(["text", "password"]).isRequired, label: PropTypes.string.isRequired, fieldId: PropTypes.string.isRequired, placeholder: PropTypes.string.isRequired, required: PropTypes.bool, children: PropTypes.node, validator: PropTypes.func, onStateChanged: PropTypes.func }; export default FormField;
Ta đang làm một số thứ trong thành phần này. Hãy chia nhỏ nó ra một chút:
Trạng thái đầu vào : Đầu tiên, bạn khởi tạo state
cho thành phần trường biểu mẫu để theo dõi value
hiện tại của trường đầu vào, trạng thái dirty
của trường và mọi errors
xác thực hiện có. Một trường trở nên bẩn ngay khi giá trị của nó thay đổi lần đầu tiên và vẫn còn bẩn.
Xử lý thay đổi đầu vào : Tiếp theo, bạn đã thêm trình xử lý sự kiện hasChanged(e)
để cập nhật value
trạng thái thành value
đầu vào hiện tại trên mọi thay đổi đối với đầu vào. Trong trình xử lý, bạn cũng giải quyết trạng thái dirty
của trường. Bạn kiểm tra xem trường có required
trường required
dựa trên đạo cụ hay không và thêm lỗi xác thực vào mảng errors
trạng thái nếu giá trị trống.
Tuy nhiên, nếu trường không phải là trường bắt buộc hoặc được yêu cầu nhưng không trống, thì bạn ủy quyền cho hàm xác thực được truyền trong phần hỗ trợ validator
tùy chọn, gọi nó bằng giá trị đầu vào hiện tại và thêm lỗi xác thực đã ném vào mảng errors
trạng thái (nếu có bất kỳ lỗi nào).
Cuối cùng, bạn cập nhật trạng thái và chuyển một hàm gọi lại sẽ được gọi sau khi cập nhật. Hàm gọi lại gọi hàm được truyền trong phần hỗ trợ onStateChanged
tùy chọn, chuyển trạng thái cập nhật làm đối số của nó. Điều này sẽ trở nên hữu ích cho việc truyền bá các thay đổi trạng thái bên ngoài thành phần.
Kết xuất và Đạo cụ : Tại đây bạn đang kết xuất trường đầu vào và nhãn của nó. Bạn cũng có điều kiện hiển thị lỗi đầu tiên trong mảng errors
trạng thái (nếu có bất kỳ lỗi nào). Lưu ý cách bạn đặt động các lớp cho trường đầu vào để hiển thị trạng thái xác thực bằng cách sử dụng các lớp tích hợp sẵn từ Bootstrap. Bạn cũng hiển thị bất kỳ nút con nào có trong thành phần.
Như đã thấy trong propTypes
của thành phần, các đạo cụ cần thiết cho thành phần này là type
( 'text'
hoặc 'password'
), label
, placeholder
và fieldId
. Các thành phần còn lại là tùy chọn.
Thành phần EmailField
Tạo một file mới EmailField.js
trong folder src/components
và thêm đoạn mã sau vào đó:
import React from 'react'; import PropTypes from 'prop-types'; import { validate } from 'isemail'; import FormField from './FormField'; const EmailField = props => { // prevent passing type and validator props from this component to the rendered form field component const { type, validator, ...restProps } = props; // validateEmail function using the validate() method of the isemail package const validateEmail = value => { if (!validate(value)) throw new Error('Email is invalid'); }; // pass the validateEmail to the validator prop return <FormField type="text" validator={validateEmail} {...restProps} /> }; EmailField.propTypes = { label: PropTypes.string.isRequired, fieldId: PropTypes.string.isRequired, placeholder: PropTypes.string.isRequired, required: PropTypes.bool, children: PropTypes.node, onStateChanged: PropTypes.func }; export default EmailField;
Trong thành phần EmailField
, bạn đang kết xuất một thành phần FormField
và chuyển một chức năng xác thực email đến bộ phận hỗ trợ validator
. Bạn đang sử dụng phương thức validate()
của gói isemail
để xác thực email.
Bạn cũng có thể nhận thấy rằng tất cả các đạo cụ khác, ngoại trừ các type
và validator
đạo cụ được chuyển từ EmailField
thành phần để các FormField
thành phần.
Thành phần PasswordField
Tạo một file mới PasswordField.js
trong folder src/components
và thêm đoạn mã sau vào đó:
import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import zxcvbn from 'zxcvbn'; import FormField from './FormField'; class PasswordField extends Component { constructor(props) { super(props); const { minStrength = 3, thresholdLength = 7 } = props; // set default minStrength to 3 if not a number or not specified // minStrength must be a a number between 0 - 4 this.minStrength = typeof minStrength === 'number' ? Math.max( Math.min(minStrength, 4), 0 ) : 3; // set default thresholdLength to 7 if not a number or not specified // thresholdLength must be a minimum value of 7 this.thresholdLength = typeof thresholdLength === 'number' ? Math.max(thresholdLength, 7) : 7; // initialize internal component state this.state = { password: '', strength: 0 }; }; stateChanged = state => { // update the internal state using the updated state from the form field this.setState({ password: state.value, strength: zxcvbn(state.value).score }, () => this.props.onStateChanged(state)); }; validatePasswordStrong = value => { // ensure password is long enough if (value.length <= this.thresholdLength) throw new Error("Password is short"); // ensure password is strong enough using the zxcvbn library if (zxcvbn(value).score < this.minStrength) throw new Error("Password is weak"); }; render() { const { type, validator, onStateChanged, children, ...restProps } = this.props; const { password, strength } = this.state; const passwordLength = password.length; const passwordStrong = strength >= this.minStrength; const passwordLong = passwordLength > this.thresholdLength; // dynamically set the password length counter class const counterClass = ['badge badge-pill', passwordLong ? passwordStrong ? 'badge-success' : 'badge-warning' : 'badge-danger'].join(' ').trim(); // password strength meter is only visible when password is not empty const strengthClass = ['strength-meter mt-2', passwordLength > 0 ? 'visible' : 'invisible'].join(' ').trim(); return ( <Fragment> <div className="position-relative"> {/** Pass the validation and stateChanged functions as props to the form field **/} <FormField type="password" validator={this.validatePasswordStrong} onStateChanged={this.stateChanged} {...restProps}> <span className="d-block form-hint">To conform with our Strong Password policy, you are required to use a sufficiently strong password. Password must be more than 7 characters.</span> {children} {/** Render the password strength meter **/} <div className={strengthClass}> <div className="strength-meter-fill" data-strength={strength}></div> </div> </FormField> <div className="position-absolute password-count mx-3"> {/** Render the password length counter indicator **/} <span className={counterClass}>{ passwordLength ? passwordLong ? `${this.thresholdLength}+` : passwordLength : '' }</span> </div> </div> </Fragment> ); } } PasswordField.propTypes = { label: PropTypes.string.isRequired, fieldId: PropTypes.string.isRequired, placeholder: PropTypes.string.isRequired, required: PropTypes.bool, children: PropTypes.node, onStateChanged: PropTypes.func, minStrength: PropTypes.number, thresholdLength: PropTypes.number }; export default PasswordField;
Thành phần này đang sử dụng gói ước tính độ mạnh password JavaScript zxcvbn
. Gói xuất một zxcvbn()
lấy một chuỗi password làm đối số đầu tiên của nó và trả về một đối tượng có một số thuộc tính để ước tính độ mạnh của password . Trong hướng dẫn này, ta sẽ chỉ quan tâm đến thuộc tính điểm, là một số nguyên từ 0
- 4
, có thể hữu ích cho việc triển khai thanh cường độ hình ảnh.
Dưới đây là phân tích về những gì đang xảy ra trong thành phần PasswordField
:
Khởi tạo: Trong constructor()
, bạn đã tạo hai thuộc tính Ví dụ, thresholdLangth
và minStrength
, từ prop tương ứng của họ truyền cho các thành phần. Độ dài thresholdLength
là độ dài password tối thiểu trước khi nó có thể được coi là đủ dài. Nó mặc định là 7
và không thể thấp hơn. minStrength
là điểm zxcvbn
tối thiểu trước khi password được coi là đủ mạnh. Giá trị của nó nằm trong repository ảng từ 0-4
. Nó mặc định là 3
nếu không được chỉ định.
Bạn cũng khởi tạo trạng thái bên trong của trường password để lưu trữ password
hiện tại và strength
password .
Xử lý thay đổi password : Bạn đã xác định một chức năng xác thực password sẽ được chuyển cho validator
hỗ trợ của thành phần FormField
bên dưới. Này để thỏa mãn hàm độ dài password dài hơn thresholdLength
và cũng có tối thiểu zxcvbn()
điểm của quy định minStrength
.
Bạn cũng đã định nghĩa một hàm stateChanged()
, hàm này sẽ được chuyển đến phần hỗ trợ onStateChanged
của thành phần FormField
. Hàm này truy xuất trạng thái cập nhật của thành phần FormField
và sử dụng nó để tính toán và cập nhật trạng thái bên trong mới của thành phần PasswordField
.
Hàm gọi lại sẽ được gọi sau khi cập nhật trạng thái nội bộ. Hàm gọi lại gọi hàm được truyền trong phần hỗ trợ onStateChanged
tùy chọn của thành phần PasswordField
, chuyển trạng thái FormField
cập nhật làm đối số của nó.
Kết xuất và Đạo cụ : Tại đây bạn đã kết FormField
thành phần FormField
bên dưới cùng với một số phần tử cho gợi ý đầu vào , đồng hồ đo độ mạnh mật khẩu và bộ đếm độ dài password .
Các máy đo cường độ password cho thấy strength
của dòng password
dựa trên nhà nước và được cấu hình để được tự động invisible
nếu độ dài password là 0
. Đồng hồ sẽ chỉ ra các màu sắc khác nhau cho các mức cường độ khác nhau.
Bộ đếm độ dài password cho biết khi password đủ dài. Nó hiển thị độ dài password nếu password không dài hơn Độ dài thresholdLength
, nếu không, nó hiển thị Độ dài thresholdLength
theo sau là dấu plus(+)
.
Các PasswordField
thành phần chấp nhận hai lĩnh vực tùy chọn bổ sung, minStrength
và thresholdLength
, theo quy định tại của thành phần propTypes
.
Thành phần JoinForm
Tạo một file mới JoinForm.js
trong folder src/components
và thêm đoạn mã sau vào đó:
import React, { Component } from 'react'; import FormField from './FormField'; import EmailField from './EmailField'; import PasswordField from './PasswordField'; class JoinForm extends Component { // initialize state to hold validity of form fields state = { fullname: false, email: false, password: false } // higher-order function that returns a state change watch function // sets the corresponding state property to true if the form field has no errors fieldStateChanged = field => state => this.setState({ [field]: state.errors.length === 0 }); // state change watch functions for each field emailChanged = this.fieldStateChanged('email'); fullnameChanged = this.fieldStateChanged('fullname'); passwordChanged = this.fieldStateChanged('password'); render() { const { fullname, email, password } = this.state; const formValidated = fullname && email && password; // validation function for the fullname // ensures that fullname contains at least two names separated with a space const validateFullname = value => { const regex = /^[a-z]{2,}(\s[a-z]{2,})+$/i; if (!regex.test(value)) throw new Error('Fullname is invalid'); }; return ( <div className="form-container d-table-cell position-relative align-middle"> <form action="/" method="POST" noValidate> <div className="d-flex flex-row justify-content-between align-items-center px-3 mb-5"> <legend className="form-label mb-0">Support Team</legend> {/** Show the form button only if all fields are valid **/} { formValidated && <button type="button" className="btn btn-primary text-uppercase px-3 py-2">Join</button> } </div> <div className="py-5 border-gray border-top border-bottom"> {/** Render the fullname form field passing the name validation fn **/} <FormField type="text" fieldId="fullname" label="Full Name" placeholder="Enter Full Name" validator={validateFullname} onStateChanged={this.fullnameChanged} required /> {/** Render the email field component **/} <EmailField fieldId="email" label="Email" placeholder="Enter Email Address" onStateChanged={this.emailChanged} required /> {/** Render the password field component using thresholdLength of 7 and minStrength of 3 **/} <PasswordField fieldId="password" label="Password" placeholder="Enter Password" onStateChanged={this.passwordChanged} thresholdLength={7} minStrength={3} required /> </div> </form> </div> ); } } export default JoinForm;
Thành phần JoinForm
bao bọc các thành phần trường biểu mẫu tạo nên biểu mẫu của ta . Ta đã khởi tạo trạng thái để giữ tính hợp lệ của ba trường biểu mẫu: họ fullname
, email
và password
. Tất cả chúng đều false
, hoặc invalid
, ban đầu.
Ta cũng đã xác định các chức năng đồng hồ thay đổi trạng thái cho từng trường để cập nhật trạng thái biểu mẫu cho phù hợp. Chức năng đồng hồ kiểm tra xem không có errors
nào trong một trường và cập nhật trạng thái nội bộ của biểu mẫu cho trường đó thành true
hoặc valid
. Các chức năng đồng hồ này sau đó được gán cho phần hỗ trợ onStateChanged
của mỗi thành phần trường biểu mẫu để theo dõi các thay đổi trạng thái.
Cuối cùng, biểu mẫu được hiển thị. Lưu ý bạn đã thêm một hàm xác thực vào trường fullname
đủ đảm bảo rằng ít nhất hai tên, được phân tách bằng dấu cách và chỉ chứa các ký tự trong bảng chữ cái, được cung cấp.
Thành phần App
Cho đến thời điểm này, trình duyệt vẫn hiển thị ứng dụng React bản soạn sẵn. Đến đây bạn sẽ sửa đổi file App.js
trong folder src
để hiển thị JoinForm
bên trong AppComponent
.
Tệp App.js
sẽ giống như đoạn mã sau:
import React from 'react'; import JoinForm from './components/JoinForm'; import './App.css'; function App() { return ( <div className="main-container d-table position-absolute m-auto"> <JoinForm /> </div> ); } export default App;
Bước 3 - Tạo kiểu với Sass
Bạn chỉ còn một bước nữa là đến giao diện cuối cùng cho ứng dụng của bạn . Hiện tại, mọi thứ có vẻ hơi lạc lõng. Trong bước này, bạn sẽ tiếp tục và xác định một số luật kiểu để tạo kiểu cho biểu mẫu.
Để tận dụng các biến Sass, lồng và vòng lặp mạnh mẽ, trước đây ta đã cài đặt phụ thuộc của node-sass
. Bạn đang sử dụng Sass để tạo file CSS mà trình duyệt có thể hiểu được.
Có hai điều bạn cần thay đổi để sử dụng Sass trong ứng dụng của bạn sau khi cài đặt phần phụ thuộc:
- Đổi tên file
src/App.css
thànhsrc/App.scss
. - Chỉnh sửa dòng nhập trong
src/App.js
để tham chiếu đến file đã đổi tên.
Sau khi đổi tên file src/App.css
, hãy cập nhật file src/App.js
của bạn thành như sau:
import './App.scss';
Lưu và đóng file .
Tiếp theo, thay thế nội dung hiện có trong file App.scss
bằng mã sau để định dạng ứng dụng:
/** Declare some variables **/ $primary: #007bff; // Password strength meter color for the different levels $strength-colors: (darkred, orangered, orange, yellowgreen, green); // Gap width between strength meter bars $strength-gap: 6px; body { font-size: 62.5%; } .main-container { width: 400px; top: 0; bottom: 0; left: 0; right: 0; } .form-container { bottom: 100px; } legend.form-label { font-size: 1.5rem; color: desaturate(darken($primary, 10%), 60%); } .control-label { font-size: 0.8rem; font-weight: bold; color: desaturate(darken($primary, 10%), 80%); } .form-control { font-size: 1rem; } .form-hint { font-size: 0.6rem; line-height: 1.4; margin: -5px auto 5px; color: #999; &.error { color: #C00; font-size: 0.8rem; } } button.btn { letter-spacing: 1px; font-size: 0.8rem; font-weight: 600; } .password-count { bottom: 16px; right: 10px; font-size: 1rem; } .strength-meter { position: relative; height: 3px; background: #DDD; margin: 7px 0; border-radius: 2px; // Dynamically create the gap effect &:before, &:after { content: ''; height: inherit; background: transparent; display: block; border-color: #FFF; border-style: solid; border-width: 0 $strength-gap 0; position: absolute; width: calc(20% + #{$strength-gap}); z-index: 10; } // Dynamically create the gap effect &:before { left: calc(20% - #{($strength-gap / 2)}); } // Dynamically create the gap effect &:after { right: calc(20% - #{($strength-gap / 2)}); } } .strength-meter-fill { background: transparent; height: inherit; position: absolute; width: 0; border-radius: inherit; transition: width 0.5s ease-in-out, background 0.25s; // Dynamically generate strength meter color styles @for $i from 1 through 5 { &[data-strength='#{$i - 1}'] { width: (20% * $i); background: nth($strength-colors, $i); } } }
Bạn đã thành công trong việc thêm các kiểu theo yêu cầu của ứng dụng. Lưu ý việc sử dụng nội dung CSS được tạo trong .strength-meter:before
và .strength-meter:after
các phần tử giả để thêm khoảng trống vào đồng hồ đo độ mạnh password .
Bạn cũng đã sử dụng chỉ thị Sass @for
để tạo động các màu tô cho đồng hồ đo cường độ ở các mức độ mạnh password khác nhau.
Màn hình ứng dụng cuối cùng sẽ giống như sau:
Với lỗi xác thực, màn hình sẽ như thế này:
Không có bất kỳ lỗi nào, khi tất cả các trường đều hợp lệ, màn hình sẽ như sau:
Kết luận
Trong hướng dẫn này, bạn đã tạo một đồng hồ đo độ mạnh password dựa trên thư viện JavaScript zxcvbn
trong ứng dụng React của bạn . Để có hướng dẫn sử dụng chi tiết và tài liệu của thư viện zxcvbn
, hãy xem repository zxcvbn
trên GitHub. Để có mẫu mã hoàn chỉnh của hướng dẫn này, hãy kiểm tra repository demo password -độ mạnh-phản ứng-phản ứng trên GitHub. Bạn cũng có thể nhận bản demo trực tiếp của hướng dẫn này trên Code Sandbox .
Nếu bạn quan tâm đến version AngularJS của bài viết này, bạn có thể xem qua: Máy đo độ mạnh password trong AngularJS .
Các tin liên quan