当前位置:   article > 正文

网络安全SQL注入

网络安全SQL注入

HTML & Vue.js 结合使用

HTML 是网页的基础结构语言,而 Vue.js 是一个用于构建用户界面的渐进式JavaScript框架。结合两者,你可以创建动态、响应式的Web应用程序。Vue.js通过指令(如v-bind, v-if, v-for)无缝集成到HTML中,使得数据绑定和页面逻辑变得更加直观。

示例

  1. <div id="app">
  2. <h1>{{ message }}</h1>
  3. <input v-model="message">
  4. </div>
  5. <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  6. <script>
  7. new Vue({
  8. el: '#app',
  9. data: {
  10. message: 'Hello Vue!'
  11. }
  12. })
  13. </script>

 

Vue.js 与 Spring Boot 后端集成

在前后端分离的架构中,Vue.js 负责前端展示与交互,而 Spring Boot 提供后端服务。两者通常通过API进行通信,常用的技术栈包括 RESTful API 和 Axios(Vue端的HTTP库)。

Vue.js 请求Spring Boot API示例

  1. axios.get('http://localhost:8080/api/users')
  2. .then(response => {
  3. this.users = response.data;
  4. })
  5. .catch(error => {
  6. console.error("Error fetching data: ", error);
  7. });

MyBatis 与 Spring Boot 集成

MyBatis 是一个优秀的持久层框架,它支持自定义SQL,可以将SQL查询映射到Java对象。在Spring Boot中,通过MyBatis-Spring-Boot-Starter可以轻松集成。

配置示例application.ymlapplication.properties):

  1. mybatis.type-aliases-package=com.example.demo.entity
  2. mybatis.mapper-locations=classpath:mapper/*.xml

Java 重写与重载

  • 重写(Overriding):在继承关系中,子类可以提供一个与其父类方法签名完全相同的方法实现。这允许子类改变父类的行为。重写要求方法名、参数列表、返回类型必须与父类方法一致,且访问权限不能比父类更严格。

  • 重载(Overloading):发生在同一个类中,方法名相同但参数列表不同(参数类型、数量或顺序不同)。重载方法可以有不同的返回类型,但这是根据参数列表区分的,而不是返回类型。

MyBatis 自定义类型处理器

自定义类型处理器允许你改变MyBatis处理特定类型数据的方式,例如,自定义字符串类型处理器来处理特殊格式的数据。

示例

  1. package com.example.mapper.handlers;
  2. import org.apache.ibatis.type.BaseTypeHandler;
  3. import org.apache.ibatis.type.JdbcType;
  4. import org.apache.ibatis.type.MappedTypes;
  5. import java.sql.CallableStatement;
  6. import java.sql.PreparedStatement;
  7. import java.sql.ResultSet;
  8. import java.sql.SQLException;
  9. @MappedTypes(String.class)
  10. public class CustomStringTypeHandler extends BaseTypeHandler<String> {
  11. @Override
  12. public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
  13. ps.setString(i, customProcess(parameter));
  14. }
  15. @Override
  16. public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
  17. return customProcess(rs.getString(columnName));
  18. }
  19. @Override
  20. public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  21. return customProcess(rs.getString(columnIndex));
  22. }
  23. @Override
  24. public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  25. return customProcess(cs.getString(columnIndex));
  26. }
  27. private String customProcess(String input) {
  28. // 在这里实现你的自定义处理逻辑
  29. return input.toUpperCase(); // 示例:将字符串转为大写
  30. }
  31. }

通过以上示例,你可以看到如何将这些技术结合起来,构建一个从前端展示到后端数据处理的完整Web应用流程。从Vue.js的前端界面到Spring Boot后端服务,再到MyBatis处理数据库交互,每一步都是现代Web应用开发的关键环节。

在Web应用开发中,Thymeleaf 作为模板引擎常用于Spring Boot项目中,Vue.js 则用于构建动态的前端界面。当结合MyBatis和Spring Boot后端进行数据库操作时,防范SQL注入攻击是至关重要的。以下是一个结合Thymeleaf、Vue.js、MyBatis和Spring Boot的示例,通过一个登录功能,来具体说明SQL注入攻击及其预防方法。

前端(Vue.js 或 Thymeleaf)

首先,我们看前端如何接收用户输入并提交到后端。

  1. <!-- login.vue -->
  2. <template>
  3. <form @submit.prevent="login">
  4. <input type="text" v-model="username" placeholder="Username" />
  5. <input type="password" v-model="password" placeholder="Password" />
  6. <button>Login</button>
  7. </form>
  8. </template>
  9. <script>
  10. export default {
  11. data() {
  12. return {
  13. username: '',
  14. password: ''
  15. };
  16. },
  17. methods: {
  18. async login() {
  19. await axios.post('/api/login', { username: this.username, password: this.password });
  20. }
  21. }
  22. };
  23. </script>
Thymeleaf 示例
  1. <!-- login.html -->
  2. <form th:action="@{/api/login}" method="post">
  3. <input type="text" name="username" placeholder="Username" />
  4. <input type="password" name="password" placeholder="Password" />
  5. <button type="submit">Login</button>
  6. </form>

后端(Spring Boot + MyBatis)

后端接收到前端提交的数据后,需要正确处理以防止SQL注入。

  1. // UserController.java
  2. @PostMapping("/api/login")
  3. public ResponseEntity<?> login(@RequestParam String username, @RequestParam String password) {
  4. User user = userService.login(username, password);
  5. if (user != null) {
  6. return ResponseEntity.ok("Login successful");
  7. } else {
  8. return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
  9. }
  10. }
  11. // UserService.java
  12. public User login(String username, String password) {
  13. String query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
  14. return jdbcTemplate.queryForObject(query, new UserRowMapper());
  15. }
安全的示例(使用MyBatis)

使用MyBatis的Mapper接口和PreparedStatement来防止SQL注入。

  1. // UserMapper.java
  2. @Mapper
  3. public interface UserMapper {
  4. @Select("SELECT * FROM users WHERE username = #{username} AND password = #{password}")
  5. User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
  6. }
  7. // UserService.java
  8. @Service
  9. public class UserService {
  10. @Autowired
  11. private UserMapper userMapper;
  12. public User login(String username, String password) {
  13. return userMapper.findByUsernameAndPassword(username, password);
  14. }
  15. }

表结构设计参考

  1. CREATE TABLE `users` (
  2. `id` INT(11) NOT NULL AUTO_INCREMENT,
  3. `username` VARCHAR(255) NOT NULL,
  4. `password` VARCHAR(255) NOT NULL, -- 实际存储的是密码的哈希值
  5. `email` VARCHAR(255),
  6. `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  7. `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  8. PRIMARY KEY (`id`),
  9. UNIQUE KEY `uk_username` (`username`) -- 确保用户名唯一
  10. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

实体类设计

  1. package com.example.demo.entity;
  2. import java.time.LocalDateTime;
  3. public class User {
  4. private Integer id;
  5. private String username;
  6. private String password; // 存储的是密码的哈希值
  7. private String email;
  8. private LocalDateTime createdAt;
  9. private LocalDateTime updatedAt;
  10. // Getter and Setter methods
  11. public Integer getId() {
  12. return id;
  13. }
  14. public void setId(Integer id) {
  15. this.id = id;
  16. }
  17. public String getUsername() {
  18. return username;
  19. }
  20. public void setUsername(String username) {
  21. this.username = username;
  22. }
  23. public String getPassword() {
  24. return password;
  25. }
  26. public void setPassword(String password) {
  27. this.password = password; // 实际应用中,这里应该是设置密码的哈希值
  28. }
  29. public String getEmail() {
  30. return email;
  31. }
  32. public void setEmail(String email) {
  33. this.email = email;
  34. }
  35. public LocalDateTime getCreatedAt() {
  36. return createdAt;
  37. }
  38. public void setCreatedAt(LocalDateTime createdAt) {
  39. this.createdAt = createdAt;
  40. }
  41. public LocalDateTime getUpdatedAt() {
  42. return updatedAt;
  43. }
  44. public void setUpdatedAt(LocalDateTime updatedAt) {
  45. this.updatedAt = updatedAt;
  46. }
  47. }

请注意,在实际应用中,密码不应明文存储,而是存储其哈希值。此外,为了进一步增强安全性,可以考虑使用加盐哈希(salted hash)或更现代的密码散列函数,如BCrypt。

SQL注入解释

在不安全的示例中,直接拼接SQL字符串,如果用户输入为 admin' OR '1'='1 作为用户名,任何密码都会导致SQL语句变为

 WHERE username = 'admin' OR '1'='1' AND password = '...'

,因为 '1'='1' 永远为真,所以该查询会匹配所有用户,造成SQL注入攻击。

而在安全示例中,通过MyBatis的#{}语法和PreparedStatement,框架会自动对参数进行转义,确保特殊字符被安全处理,防止了SQL注入的发生。

结合Vue.js或Thymeleaf的前端界面,使用Spring Boot和MyBatis构建后端时,务必采用参数化查询来防止SQL注入,确保应用的安全性。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/521006
推荐阅读
相关标签
  

闽ICP备14008679号