【问题标题】:How do I prevent user's credentials from being displayed on URL?如何防止用户的凭据显示在 URL 上?
【发布时间】:2023-01-04 22:13:12
【问题描述】:

我有一个 NextJS 应用程序,它有时无法按预期工作。

当我的连接速度较慢且网站的首次加载时间比正常情况下长时,当我尝试登录应用程序时,会执行 HTML 表单的默认行为,并且我插入的凭据会显示在 URL 上,甚至虽然我在提交函数中有一个event.preventDefault(),但我没有使用 GET。

我已经尝试提高应用程序的性能并减少页面的首次加载,但是,如果用户可以让加载时间变慢,它就可以被利用。

我只想防止凭据显示在 URL 上。 它可以替换为任何类型的其他错误。

这是我的代码:

  async function handleLogin(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setIsLoadingLogin(true);
    setError('');
    const captchaValue = await captchaRef.current?.executeAsync();
    if (!captchaValue) {
      setError('Erro de captcha. Tente novamente mais tarde.');
      return setIsLoadingLogin(false);
    }
    try {
      const { access, refresh } = await loginService({
        email,
        password,
        captcha_value: captchaValue,
      });
      setCookie(undefined, cookieNames.userAccessToken, access);
      setCookie(undefined, cookieNames.userRefreshToken, refresh);
      await router.push('/home');
    } catch (error: any) {
      if (error.response.status === 500) return setError('Erro no servidor.');
      if (error.response.data.detail) return setError(error.response.data.detail);
    } finally {
      setIsLoadingLogin(false);
      setPassword('');
      captchaRef.current?.reset();
    }
  }


<form onSubmit={handleLogin}>
...
</form>

【问题讨论】:

  • 使用 POST 方法而不是 GET
  • 我已经在使用 POST,这里的问题是函数没有执行。
  • 你能分享你的代码吗?也许event.preventDefault()有时没有执行,因为在到达语句之前发生异常?

标签: javascript performance authentication security next.js


【解决方案1】:

您可以使用 fetch API 或类似 axios 的库从客户端发送 POST 请求。下面是一个示例,说明如何使用 fetch 在 Next.js 中发送带有表单负载的 POST 请求:

import { useState } from 'react'

function LoginForm() {
  const [formData, setFormData] = useState({})

  const handleChange = (event) => {
    const { name, value } = event.target
    setFormData((formData) => ({
      ...formData,
      [name]: value
    }))
  }

  const handleSubmit = (event) => {
    event.preventDefault()

    fetch('/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(formData)
    })
    .then((response) => response.json())
    .then((data) => console.log(data))
  }

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" name="username" onChange={handleChange} />
      <input type="password" name="password" onChange={handleChange} />
      <button type="submit">Log In</button>
    </form>
  )
}

【讨论】:

    【解决方案2】:

    在 NextJs 中,您可以通过使用服务器端身份验证流程来防止用户的凭据显示在 URL 中。这意味着身份验证过程将在服务器上进行,而不是在客户端上进行。下面是一个示例,说明如何使用 PassportJS 库在 NextJS 中实现服务器端身份验证:

    1. 安装 PassportJS 和所需的身份验证策略(例如用于用户名和密码身份验证的 passport-local):
      npm install passport passport-local
      
      
      1. 在您的 NextJS 服务器中配置 PassportJS 和身份验证策略:
      const passport = require('passport');
      const LocalStrategy = require('passport-local').Strategy;
      
      passport.use(new LocalStrategy(
        function(username, password, done) {
          // Verify the username and password
          // If the credentials are valid, call done() with the user object
          // If the credentials are invalid, call done(null, false)
        }
      ));
      
      app.use(passport.initialize());
      app.use(passport.session());
      
      
      1. 添加使用 PassportJS 对用户进行身份验证的登录路由:
      app.post('/login', passport.authenticate('local'), (req, res) => {
        // If the authentication is successful, a user object will be available in req.user
        // You can store the user object in a session or set a cookie to keep the user logged in
        res.json({ user: req.user });
      });
      
      
      1. 添加销毁用户会话或清除用户 cookie 的注销路由:
      app.get('/logout', (req, res) => {
        req.logout();
        res.redirect('/');
      });
      
      

      通过使用服务器端身份验证,您可以防止用户的凭据通过网络传输或显示在 URL 中。

      我希望这能以某种方式有所帮助。

    【讨论】:

      猜你喜欢
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-08
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多