Как отправить пароль в зашифрованном виде с ReactJS на ExpressJS?

const form = {
        firstname: "",
        lastname: "",
        email: "",
        password: "",
        gender: "",
        dob: "",
        username: ""
};

export default class Login extends React.Component {
  constructor (props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.state = {
    }
  }

  handleSubmit (event) {
    event.preventDefault();
    api.signin(this.state)
  }

  handleChange (event, type) {
    form[type] = event.target.value;
    this.setState({
      form
    })
  }

  render() {
    return (
      <div>
        <nav className="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
          <a className="navbar-brand" href="#">ChatBox</a>
          <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault">
            <span className="navbar-toggler-icon"></span>
          </button>

          <div className="collapse navbar-collapse" id="navbarsExampleDefault">
            <ul className="navbar-nav mr-auto">
              <li className="nav-item active">
                <a className="nav-link" href="#">Home <span className="sr-only">(current)</span></a>
              </li>
              <li className="nav-item">
                <a className="nav-link" href="#">Link</a>
              </li>
              <li className="nav-item">
                <a className="nav-link" href="#">Disabled</a>
              </li>
              <li className="nav-item dropdown">
                <a className="nav-link dropdown-toggle" href="http://example.com" id="dropdown01" data-toggle="dropdown">Dropdown</a>
                <div className="dropdown-menu" aria-labelledby="dropdown01">
                  <a className="dropdown-item" href="#">Action</a>
                  <a className="dropdown-item" href="#">Another action</a>
                  <a className="dropdown-item" href="#">Something else here</a>
                </div>
              </li>
            </ul>
          </div>
        </nav>
        <main role="main" className="container">
          <div className="starter-template">
            <h1>Register for ChatBox</h1>
            <form >
              <div className="d-flex justify-content-center bd-highlight mb-3">
                <div className="p-2">
                  <label htmlFor="firstname">First Name</label>
                  <input type="text" className="form-control" id="firstname" placeholder="First Name" onChange={
                    (e)=>{ this.handleChange(e, 'firstname')}
                  }/>
                </div>
                <div className="p-2">
                  <label htmlFor="lastname">Last Name</label>
                  <input type="text" className="form-control" id="lastname" placeholder="Last Name" onChange={
                    (e)=>{ this.handleChange(e, 'lastname')}
                  } />
                </div>
              </div>
              <div className="form-group col-md-6">
                <label htmlFor="inputEmail4">Email</label>
                <input type="email" className="form-control" id="inputEmail4" placeholder="Email" onChange={
                    (e)=>{ this.handleChange(e, 'email')}
                  }/>
              </div>
              <div className="form-group col-md-6">
                <label htmlFor="username">Username</label>
                <input type="text" className="form-control" id="username" placeholder="Username" onChange={
                    (e)=>{ this.handleChange(e, 'username')}
                  }/>
              </div>
              <div className="form-group col-md-6">
                <label htmlFor="inputPassword4">Password</label>
                <input type="password" className="form-control" id="inputPassword4" placeholder="Password" onChange={
                    (e)=>{ this.handleChange(e, 'password')}
                  }/>
              </div>
              <div className="form-group col-md-6">
                <label htmlFor="gender">Gender</label>
                <select id="gender" className="form-control" onChange={ (e)=>{ this.handleChange(e, 'gender')} }>
                  <option >Choose...</option>
                  <option value="male">Male</option>
                  <option value="female">Female</option>
                </select>
              </div>
              <div className="form-group col-md-6 " >
                <label htmlFor="date">D.O.B</label>
                <input type="date" className="form-control" id="date" placeholder="date" onChange={ (e)=>{ this.handleChange(e, 'dob')} }/>
              </div>
              <div className="form-group col-md-2">
                <input type="submit" onClick={this.handleSubmit} className="form-control bg-info text-white" id="submit" placeholder="Password" />
              </div>
            </form>
          </div>
        </main>
      </div>
    )
  }
}

Это хорошая практика для хранения данных формы в таком состоянии или есть какой-то лучший способ?

и введенный пароль можно увидеть как обычный текст из devtools. Как избежать этого, я имею в виду любой способ зашифровать пароль и отправить его на сервер.

Я очень новичок в этом. Будет полезно, если кто-нибудь проверит, является ли это хорошей практикой для написания кода.

3 ответа

Решение

Как было сказано ранее, вы не можете запретить пользователю просматривать пароль в своем браузере (кроме того, он является пользователем, поэтому он уже знает пароль). Хранить пароль опасно, поскольку он подвергается атакам локальной файловой системы (против которых может быть полезно шифрование, если вы используете разные ключи для каждого пользователя).

Возможно, вы захотите зашифровать пароль, если не доверяете SSL / TLS (например, корпоративные пользователи могут быть вынуждены использовать небезопасное соединение HTTP с некоторыми прокси-серверами HTTPS). Но в этом случае вы можете вместо этого доказать серверу, что у клиента есть пароль, не отправляя его вообще (даже зашифрованный, для которого ключ шифрования должен был бы делиться с клиентом через ненадежную сеть, что является плохой идеей), отправив хеш пароля плюс некоторые несекретные псевдослучайные вещи (и отправьте псевдослучайные вещи тоже).

При этом вы не должны хранить пароль пользователя в какой-либо форме на стороне клиента (при аутентификации вы все равно можете отправлять хеш, полученный из пароля, вместо самого пароля, в случае, если HTTPS скомпрометирован).

Сохраните токен (например, токен доступа OIDC), сгенерированный сервером после первоначальной аутентификации. Срок действия токена истекает (обычно от часа до пары дней), его можно отозвать с минимальными неудобствами для пользователя (ему не нужно создавать новый пароль), и его недостаточно для изменения пароля пользователя или адреса электронной почты (обычно пользователь должен будет ввести старый пароль для этого) и выполнить другие важные операции с учетной записью, чтобы пользователь мог по крайней мере восстановить учетную запись, даже если какой-либо ущерб был нанесен с помощью украденного токена.

Нет необходимости в таком шифровании. Было бы бессмысленно внедрять собственное шифрование, поскольку именно по этой причине был создан HTTPS.

Вам не нужно шифровать пароль во внешнем интерфейсе перед его отправкой на сервер, если вы используете соединение HTTPS и отправляете его в качестве параметров формы. Однако вам не следует хранить пароль в локальном хранилище браузера, вы можете запросить у бэкэнда токен подключения, который вы сохраните в качестве идентификатора сеанса.

Другие вопросы по тегам