springboot+security 的BCryptPasswordEncoder 使用

博客强调应用安全不应明文保存密码,可通过哈希算法加密,如结合salt的SHA或MD5。Spring Security提供BCryptPasswordEncoder类用BCrypt强哈希方法加密,每次结果不同。还提及修改WebSecurityConfig进行整合,以及密码初始化和注册加密等问题。

任何应用考虑到安全,绝不能明文的方式保存密码。密码应该通过哈希算法进行加密。有很多标准的算法比如SHA或者MD5,结合salt(盐)是一个不错的选择。 Spring Security 提供了BCryptPasswordEncoder类,实现Spring的PasswordEncoder接口使用BCrypt强哈希方法来加密密码。

BCrypt强哈希方法 每次加密的结果都不一样。

好了废话不多说,就看怎么整合吧。。

1. 修改 WebSecurityConfig

    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserService).passwordEncoder(new BCryptPasswordEncoder());
    }

这样配置就好了。但是关于怎么初始化密码呢,和注册用户的时候怎么给密码加密呢?

  public SysUser create(User u user){
        //进行加密
        BCryptPasswordEncoder encoder =new BCryptPasswordEncoder();
        sysUser.setPassword(encoder.encode(user.getRawPassword().trim()));
        userDao.create(user);
    return sysUser;

虽然每次 BCryptPasswordEncoder 的 encoder 结果都不一样,但是存贮其中一次加密结果 也能够验证成功

使用 **Spring Boot + Spring Security + Thymeleaf** 实现一个简单的商城系统,是一个非常典型的 Java Web 开发项目。下面我将从零开始,详细讲解如何搭建这样一个系统,包括用户认证、权限控制、商品展示、购物车功能等核心模块。 --- ## ✅ 一、项目结构概览 ``` mall-system/ ├── src/main/java/ │ └── com/example/mall/ │ ├── MallApplication.java // 主启动类 │ ├── controller/ │ │ ├── HomeController.java // 首页与商品展示 │ │ ├── AuthController.java // 登录注册 │ │ └── CartController.java // 购物车操作 │ ├── service/ │ │ ├── UserService.java │ │ ├── ProductService.java │ │ └── CartService.java │ ├── repository/ │ │ ├── UserRepository.java │ │ ├── ProductRepository.java │ │ └── CartItemRepository.java │ ├── model/ │ │ ├── User.java │ │ ├── Product.java │ │ └── CartItem.java │ └── config/ │ └── SecurityConfig.java // 安全配置 ├── src/main/resources/ │ ├── templates/ // Thymeleaf 模板 │ │ ├── index.html │ │ ├── login.html │ │ ├── register.html │ │ ├── products.html │ │ └── cart.html │ └── application.yml // 配置文件 └── pom.xml // Maven 依赖 ``` --- ## ✅ 二、Maven 依赖(`pom.xml`) ```xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>mall</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.0</version> <relativePath/> </parent> <dependencies> <!-- Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Thymeleaf --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity6</artifactId> </dependency> <!-- Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- JPA & MySQL --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- DevTools --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> ``` --- ## ✅ 三、实体类定义 ### 1. `User.java` 用户 ```java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = true) private String username; private String password; private String role; // ROLE_USER, ROLE_ADMIN // 构造函数 public User() {} public User(String username, String password, String role) { this.username = username; this.password = password; this.role = role; } // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } } ``` ### 2. `Product.java` 商品 ```java @Entity @Table(name = "products") public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String description; private Double price; // 构造函数 public Product() {} public Product(String name, String description, Double price) { this.name = name; this.description = description; this.price = price; } // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } } ``` ### 3. `CartItem.java` 购物车条目 ```java @Entity @Table(name = "cart_items") public class CartItem { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name = "user_id") private User user; @ManyToOne @JoinColumn(name = "product_id") private Product product; private Integer quantity; public CartItem() {} public CartItem(User user, Product product, Integer quantity) { this.user = user; this.product = product; this.quantity = quantity; } // Getters and Setters public Long getId() { return id; } public void setId(Long id) { this.id = id; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } public Integer getQuantity() { return quantity; } public void setQuantity(Integer quantity) { this.quantity = quantity; } } ``` --- ## ✅ 四、Repository 接口 ```java public interface UserRepository extends JpaRepository<User, Long> { Optional<User> findByUsername(String username); } public interface ProductRepository extends JpaRepository<Product, Long> {} public interface CartItemRepository extends JpaRepository<CartItem, Long> { List<CartItem> findByUser(User user); } ``` --- ## ✅ 五、Security 配置 ### `SecurityConfig.java` ```java @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/", "/products", "/register", "/css/**").permitAll() .requestMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() ) .formLogin(login -> login .loginPage("/login") .defaultSuccessUrl("/products") .permitAll() ) .logout(logout -> logout .logoutSuccessUrl("/") .permitAll() ); return http.build(); } } ``` --- ## ✅ 六、控制器示例 ### 1. `AuthController.java` - 登录注册 ```java @Controller public class AuthController { @Autowired private UserRepository userRepository; @Autowired private PasswordEncoder passwordEncoder; @GetMapping("/register") public String showRegisterForm(Model model) { model.addAttribute("user", new User()); return "register"; } @PostMapping("/register") public String registerUser(@ModelAttribute User user) { user.setPassword(passwordEncoder.encode(user.getPassword())); user.setRole("ROLE_USER"); userRepository.save(user); return "redirect:/login"; } @GetMapping("/login") public String login() { return "login"; } } ``` ### 2. `HomeController.java` - 首页与商品 ```java @Controller public class HomeController { @Autowired private ProductRepository productRepository; @GetMapping("/") public String home() { return "index"; } @GetMapping("/products") public String listProducts(Model model) { model.addAttribute("products", productRepository.findAll()); return "products"; } } ``` ### 3. `CartController.java` - 购物车 ```java @Controller public class CartController { @Autowired private CartItemRepository cartItemRepository; @Autowired private ProductRepository productRepository; @Autowired private UserRepository userRepository; @GetMapping("/cart") public String viewCart(Model model, Authentication authentication) { String username = authentication.getName(); User user = userRepository.findByUsername(username).orElse(null); if (user != null) { List<CartItem> items = cartItemRepository.findByUser(user); model.addAttribute("cartItems", items); } return "cart"; } @PostMapping("/cart/add") public String addToCart(@RequestParam Long productId, @RequestParam(defaultValue = "1") Integer quantity, Authentication authentication) { String username = authentication.getName(); User user = userRepository.findByUsername(username).orElse(null); Product product = productRepository.findById(productId).orElse(null); if (user != null && product != null) { CartItem item = new CartItem(user, product, quantity); cartItemRepository.save(item); } return "redirect:/products"; } } ``` --- ## ✅ 七、Thymeleaf 页面模板 ### `templates/index.html` ```html <!DOCTYPE html> <html> <head><title>商城首页</title></head> <body> <h1>欢迎来到我们的商城!</h1> <a href="/products">浏览商品</a> | <a href="/login">登录</a> | <a href="/register">注册</a> </body> </html> ``` ### `templates/products.html` ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head><title>商品列表</title></head> <body> <h1>所有商品</h1> <div th:each="product : ${products}"> <h3 th:text="${product.name}"></h3> <p th:text="${product.description}"></p> <p>价格: <span th:text="${product.price}"></span> 元</p> <form th:action="@{/cart/add}" method="post"> <input type="hidden" name="productId" th:value="${product.id}" /> <input type="number" name="quantity" value="1" min="1" /> <button type="submit">加入购物车</button> </form> </div> <a href="/cart">查看购物车</a> </body> </html> ``` ### `templates/cart.html` ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head><title>购物车</title></head> <body> <h1>我的购物车</h1> <ul> <li th:each="item : ${cartItems}"> [[${item.product.name}]] × [[${item.quantity}]] (总价: [[${item.quantity * item.product.price}]]) </li> </ul> <a href="/products">继续购物</a> </body> </html> ``` ### `templates/login.html` ```html <!DOCTYPE html> <html> <head><title>登录</title></head> <body> <h2>登录</h2> <form th:action="@{/login}" method="post"> <input type="text" name="username" placeholder="用户名" required /> <input type="password" name="password" placeholder="密码" required /> <button type="submit">登录</button> </form> <p><a href="/register">没有账号?去注册</a></p> </body> </html> ``` --- ## ✅ 八、数据库配置(`application.yml`) ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/mall_db?useSSL=false&serverTimezone=UTC username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true thymeleaf: cache: false enabled: true prefix: classpath:/templates/ suffix: .html ``` > ⚠️ 启动前请确保已创建数据库:`CREATE DATABASE mall_db;` --- ## ✅ 九、运行项目 1. 创建数据库 `mall_db` 2. 运行 `MallApplication.java` 主类 3. 访问: - 注册:`http://localhost:8080/register` - 登录:`http://localhost:8080/login` - 商品页:`http://localhost:8080/products` - 购物车:`http://localhost:8080/cart` --- ## ✅ 十、可扩展功能建议 - 添加订单模块(Order、OrderItem) - 支持分页和搜索商品 - 管理员后台管理商品 - 使用 Spring Data REST 提供 API - 增加邮箱验证或验证码注册 - 使用 Redis 缓存购物车提升性能 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值