🔥关注墨瑾轩,带你探索编程的奥秘!🚀
🔥超萌技术攻略,轻松晋级编程高手🚀
🔥技术宝库已备好,就等你来挖掘🚀
🔥订阅墨瑾轩,智趣学习不孤单🚀
🔥即刻启航,编程之旅更有趣🚀

在这里插入图片描述在这里插入图片描述

5步打造Spring Security自定义登录界面

1. 创建自定义登录页面:别让UI设计师哭晕在厕所

灵魂拷问:为什么我们总想用默认登录页?

“因为太懒了!但别忘了,这是用户第一次接触你的产品,丑一点,用户可能就走了。”

1.1 创建login.html(Thymeleaf版)
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录 - 专业级应用</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
            height: 100vh;
            margin: 0;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .login-container {
            background: white;
            border-radius: 12px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            width: 400px;
            padding: 40px;
        }
        h1 {
            color: #2575fc;
            text-align: center;
            margin-bottom: 30px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
        }
        input {
            width: 100%;
            padding: 12px;
            border: 1px solid #ddd;
            border-radius: 6px;
            font-size: 16px;
            transition: border-color 0.3s;
        }
        input:focus {
            outline: none;
            border-color: #2575fc;
            box-shadow: 0 0 0 3px rgba(37, 117, 252, 0.2);
        }
        button {
            background: linear-gradient(to right, #2575fc, #6a11cb);
            color: white;
            border: none;
            padding: 14px 20px;
            border-radius: 6px;
            width: 100%;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: background 0.3s;
        }
        button:hover {
            background: linear-gradient(to right, #1a65e0, #5a0dab);
        }
    </style>
</head>
<body>
    <div class="login-container">
        <h1>欢迎登录</h1>
        <form action="/login" method="post">
            <div class="form-group">
                <label for="username">用户名</label>
                <input type="text" id="username" name="username" placeholder="输入您的用户名" required>
            </div>
            <div class="form-group">
                <label for="password">密码</label>
                <input type="password" id="password" name="password" placeholder="输入您的密码" required>
            </div>
            <!-- CSRF令牌:别忘了,否则登录会失败 -->
            <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
            <button type="submit">登录</button>
        </form>
    </div>
</body>
</html>

墨式注释

  • th:name="${_csrf.parameterName}"th:value="${_csrf.token}"必须的,否则CSRF攻击会阻止登录
  • 别用name="j_username"!Spring Security默认是name="username",别被老文档误导了
  • 灵魂警告:不要用<input type="hidden" name="_csrf" value="${_csrf.token}">,这会导致CSRF验证失败!

2. 配置Spring Security:别让默认配置把你坑惨

技术冷笑话

“Spring Security的默认配置就像一个‘老派绅士’,礼貌但不合时宜。”

2.1 配置SecurityConfig类
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); // 用BCrypt加密密码,别用MD5!
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
            // 1. 配置自定义登录页面
            .formLogin(formLogin -> formLogin
                .loginPage("/login") // 这里必须指向你创建的login.html路径
                .loginProcessingUrl("/login") // 登录表单提交的URL
                .defaultSuccessUrl("/home", true) // 登录成功跳转到/home
                .failureUrl("/login?error") // 登录失败跳转到/login?error
            )
            // 2. 允许访问登录页面
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/login", "/login?error").permitAll() // 重点!允许未登录访问
                .anyRequest().authenticated()
            )
            // 3. 禁用CSRF(不推荐,但有些场景下可能需要)
            .csrf(csrf -> csrf.disable())
            .build();
    }
}

技术冷知识

  • .loginPage("/login") 中的 /login控制器映射路径,不是文件路径!
  • 灵魂警告.loginProcessingUrl("/login") 必须和表单的 action 一致,否则登录会404!
  • .defaultSuccessUrl("/home", true) 中的 true 表示重定向,别忘了!

3. 处理CSRF:别让安全漏洞成为你的“黑历史”

灵魂拷问:为什么CSRF会让人头大?

“因为Spring Security默认开启CSRF保护,而自定义登录页需要手动处理CSRF令牌!”

3.1 在控制器中返回登录页面
@Controller
public class LoginController {

    @GetMapping("/login")
    public String loginPage() {
        return "login"; // 返回login.html,注意:不能用@RestController
    }
}

墨式注释

  • 必须用@Controller,不能用@RestController!因为要返回HTML页面,不是JSON
  • 别在控制器里加@ResponseBody!否则页面会变成纯文本,用户看到一堆"login"字

4. 自定义登录成功/失败处理:别让用户体验“崩”在最后

血泪教训

“有一次登录失败后,我们没处理错误信息,用户看到白屏,以为是系统挂了,直接投诉了!”

4.1 自定义登录失败处理
@Component
public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        // 重定向到登录页并带上错误信息
        response.sendRedirect("/login?error=" + exception.getMessage());
    }
}
4.2 在SecurityConfig中配置
.formLogin(formLogin -> formLogin
    .loginPage("/login")
    .loginProcessingUrl("/login")
    .defaultSuccessUrl("/home", true)
    .failureHandler(new CustomAuthenticationFailureHandler()) // 自定义失败处理
)

技术冷笑话

“错误信息要友好,别写‘用户名或密码错误’,要写‘用户名或密码不正确,请检查后再试’——这叫‘用户友好’,不是‘系统友好’。”


5. 与前端框架集成:别让登录页“割裂”在项目里

灵魂吐槽

“很多开发者把Spring Security的登录页和前端页面分开,结果用户体验差到像在用两个APP!”

5.1 与React/Vue集成(简单示例)
// 前端发送登录请求
fetch('/login', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRF-TOKEN': getCsrfToken() // 从cookie或页面获取CSRF令牌
    },
    body: JSON.stringify({
        username: 'admin',
        password: 'password'
    })
})
.then(response => {
    if (response.ok) {
        window.location.href = '/home';
    } else {
        alert('登录失败: ' + response.statusText);
    }
});

技术冷知识

  • 前端需要获取CSRF令牌,通常从/login页面的_csrf.token获取
  • 别在前端硬编码CSRF令牌!要通过API获取,否则会被CSRF攻击利用

别让“丑陋”成为你的标签

终极总结

  1. 创建专业登录页面:用CSS美化,别用默认的白底黑字
  2. 正确配置Spring Security.loginPage().loginProcessingUrl()要一致
  3. 处理CSRF:别忘了_csrf令牌,否则登录会失败
  4. 自定义成功/失败处理:提升用户体验,避免白屏
  5. 与前端集成:让登录页和整个应用融为一体

墨式结语

“下次有人问你‘Spring Security的登录页怎么改?’,别再傻乎乎地说‘我改不了’——用这5步,让它变成你的‘专业名片’!”

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐