必须用 POST。因 GET 会将密码等敏感参数暴露在 URL 中,易被历史记录、代理或日志泄露;Servlet 应仅重写 doPost() 处理登录,避免 doGet() 中实现业务逻辑,防止绕过 CSRF 防护与校验。
登录请求该用 POST 还是 GET?
必须用 POST。登录涉及密码明文传输(即使前端做了简单加密,也不改变语义),GET 会把参数拼在 URL 里,可能被浏览器历史、代理、日志记录泄露。Servlet 中若错误地用 doGet() 处理登录,表单提交后密码出现在地址栏,属于安全硬伤。
- HTML 表单的
method属性必须设为"post" - Servlet 中只重写
doPost(HttpServletRequest req, HttpServletResponse resp) - 不要在
doGet()里转发或重定向到登录页以外的逻辑——那会绕过 CSRF 防护和参数校验入口
如何安全获取并校验用户名密码?
从 req.getParameter("username") 和 req.getParameter("password") 拿值只是第一步。重点在于:不能直接拿原始字符串比对数据库明文密码(几乎没人这么干),也不能用弱哈希(如 MD5)且不加盐。
- 数据库中密码字段应存
BCrypt或PBKDF2加密后的密文(Java 推荐org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder,纯 Java SE 可用javax.crypto.SecretKeyFactory+PBKDF2WithHmacSHA256) - 校验时调用
passwordEncoder.matches(rawPassword, encodedPassword),而非equals() - 空值或长度超限(如用户名 > 32 字符)应提前拒绝,避免触发数据库查询
登录成功后怎么维持用户状态?
靠 HttpSession,不是 Cookie 本身。Servlet 容器(如 Tomcat)生成 session ID 后,默认通过名为 JSESSIONID 的 Cookie 返回给浏览器;后续请求自动携带它,服务器据此关联会话。
- 调用
req.getSession(true)获取 session,再session.setAttribute("user", user)存用户对象 - 不要把密码、token 密钥等敏感信息塞进 session —— session 数据默认存在内存或序列化到磁盘,有泄漏风险
- 设置超时:
session.setMaxInactiveInterval(30 * 60)(单位秒),避免长期空闲会话堆积 - 注意:如果前端禁用 Cookie,需启用 URL 重写(
response.encodeURL()),但现代项目基本不考虑此场景
为什么登录失败后页面总跳转不到预期位置?
常见原因是没正确处理请求转发(RequestDispatcher.forward())和重定向(response.sendRedirect())的区别,尤其在表单提交后。