目录
Java后端的登录、注册接口是怎么实现的
Java后端的登录接口是怎么实现的
Java后端的注册接口怎么实现?
如何防止SQL注入攻击?
Java后端的登录接口的实现方式有很多种,这里介绍其中一种常见的方式。
Cookie + Session 方式:用户输入用户名和密码,前端将用户提交的用户名和密码发送到后端进行验证。如果验证通过,后端会生成一个session id,然后将session id 以及其他用户信息存储在服务端的session中。同时,后端会将session id 返回给前端,前端将session id 存储在cookie中。之后,前端每次请求时都会带上cookie,后端会根据cookie中的session id 来判断用户是否已经登录,如果已经登录,则返回用户信息,否则返回未登录状态。
Token 方式:用户输入用户名和密码,前端将用户提交的用户名和密码发送到后端进行验证。如果验证通过,后端会生成一个token,然后将token 返回给前端。之后,前端每次请求时都会带上token,后端会根据token来判断用户是否已经登录,如果已经登录,则返回用户信息,否则返回未登录状态。Token 方式相对于 Cookie + Session 方式,具有更好的可扩展性和更好的跨域支持。
基于spring boot+mybatis+vue,结合 JWT 进行 token 的生成和验证,后端代码可以按照以下步骤进行编写:
添加依赖:在pom.xml文件中添加spring-boot-starter-security和jjwt依赖。
配置Spring Security:在Spring Security配置类中添加JWT过滤器,用于生成和验证token。
编写登录接口:在Controller中编写登录接口,接收用户名和密码,验证通过后生成token并返回给前端。
编写拦截器:在拦截器中验证token的有效性,如果token无效则返回错误信息。
编写注销接口:在Controller中编写注销接口,用于注销当前用户的token。
编写token生成工具类:编写一个工具类,用于生成和解析token。
编写用户认证逻辑:编写用户认证逻辑,用于验证用户的身份信息。
使用Spring Boot + MyBatis + JWT:
@RestController
@RequestMapping("/api")
public class LoginController {
@Autowired
private UserService userService;
@PostMapping("/login")
public ResponseEntity> login(@RequestBody User user) {
User loginUser = userService.login(user);
if (loginUser != null) {
String token = JWT.create()
.withAudience(loginUser.getId().toString())
.sign(Algorithm.HMAC256(loginUser.getPassword()));
return ResponseEntity.ok(token);
} else {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
}
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JWTAuthenticationFilter(authenticationManager()))
.addFilter(new JWTAuthorizationFilter(authenticationManager(), userService))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/swagger-ui.html", "/swagger-resources/**", "/v2/api-docs", "/webjars/**");
}
}
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
setFilterProcessesUrl("/api/login");
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
User user = (User) authResult.getPrincipal();
String token = JWT.create()
.withAudience(user.getId().toString())
.sign(Algorithm.HMAC256(user.getPassword()));
response.addHeader("Authorization", "Bearer " + token);
}
}
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
private UserService userService;
public JWTAuthorizationFilter(AuthenticationManager authenticationManager, UserService userService) {
super(authenticationManager);
this.userService = userService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Bearer ")) {
chain.doFilter(request, response);
return;
}
UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(request);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
chain.doFilter(request, response);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (token != null) {
String userId = JWT.require(Algorithm.HMAC256(userService.getById(Long.parseLong(JWT.decode(token.replace("Bearer ", "")).getAudience())).getPassword()))
.build()
.verify(token.replace("Bearer ", ""))
.getAudience()
.get(0);
if (userId != null) {
User user = userService.getById(Long.parseLong(userId));
return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
}
return null;
}
return null;
}
}
@Service
public class UserServiceImpl implements UserService, UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public User login(User user) {
User loginUser = userMapper.getByUsername(user.getUsername());
if (loginUser != null && new BCryptPasswordEncoder().matches(user.getPassword(), loginUser.getPassword())) {
return loginUser;
}
return null;
}
@Override
public User getById(Long id) {
return userMapper.getById(id);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.getByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found with username: " + username);
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
Java后端的注册接口的实现方式有很多种,这里介绍其中一种常见的方式。
一般来说,注册接口需要进行数据库的基本操作,而且是前后端分离式开发。总的来说就是首先进行数据库的设计,然后根据数据库进行编写服务端API接口,接着来到客户端或移动端,进行登录与注册的界面设计,接收服务端提供的数据并显示在界面上。
以下是一个简单的注册接口实现方式:
SQL注入攻击是一种常见的网络攻击方式,它可以通过恶意的SQL语句来篡改数据库或者获取敏感信息。以下是一些防止SQL注入攻击的方法:
使用参数化查询:使用参数化查询可以将用户输入的数据与SQL语句分离,从而避免了SQL注入攻击。在Java中,可以使用PreparedStatement类来实现参数化查询。
过滤用户输入:在用户输入数据之前,对数据进行过滤和验证,确保数据的合法性和安全性。例如,可以使用正则表达式来限制用户输入的字符集。
使用ORM框架:ORM框架可以自动将用户输入的数据转换为SQL语句,从而避免了手动编写SQL语句的风险。例如,Hibernate和MyBatis都是常用的ORM框架。
限制数据库用户权限:将数据库用户的权限限制在最小范围内,只允许其执行必要的操作,可以减少SQL注入攻击的危害。
使用存储过程:存储过程可以将SQL语句封装在一个过程中,从而避免了手动编写SQL语句的风险。此外,存储过程还可以提高SQL语句的执行效率。