JAVA面试题分享五百二十四:使用 Spring Boot + Hutool 实现 JWT Token 生成及拦截功能

目录

添加 Maven 依赖

配置application.properties

编写核心代码

JWT Token 生成及拦截功能

拦截器

配置拦截器

编写控制器和页面

控制器

页面


这一系列课程将包含Spring Boot 许多关键的技术和工具,包括 Mybatis-Plus、Redis、Mongodb、MinIO、Kafka、MySQL、消息队列(MQ)、OAuth2 等相关内容。

使用 Spring Boot + Hutool 实现 JWT Token 生成及拦截功能

在使用 Spring Boot 和 Hutool 实现 JWT Token 生成及拦截功能时,首先需要在项目中配置相关的依赖和属性。以下是一个简单的示例,包括了pom.xml的配置、application.properties的属性配置以及页面显示和处理逻辑代码。

添加 Maven 依赖

在 pom.xml 文件中添加 Spring Boot 和 Hutool 的相关依赖:

<!-- Spring Boot Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Hutool工具类库 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.10</version> <!-- 使用时请替换为最新版本 -->
</dependency>

<!-- JWT依赖 -->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version> <!-- 使用时请替换为最新版本 -->
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

配置application.properties

在 application.properties 中配置 JWT 相关属性:

# JWT配置
jwt.secret=your-secret-key
jwt.expiration=3600 # Token过期时间,单位秒

编写核心代码

JWT Token 生成及拦截功能
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class JwtUtil {

    @Value("${jwt.secret}")
    private String secret;

    @Value("${jwt.expiration}")
    private long expiration;

    public String generateToken(String username) {
        Date now = new Date();
        Date expiryDate = new Date(now.getTime() + expiration * 1000);

        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(now)
                .setExpiration(expiryDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    public String getUsernameFromToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();

        return claims.getSubject();
    }

    // 添加其他JWT验证和解析方法...
}
拦截器
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class JwtInterceptor implements HandlerInterceptor {

    private final JwtUtil jwtUtil;

    public JwtInterceptor(JwtUtil jwtUtil) {
        this.jwtUtil = jwtUtil;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从请求头中获取token
        String token = request.getHeader("Authorization");

        if (token != null && token.startsWith("Bearer ")) {
            // 去除Bearer前缀
            token = token.substring(7);

            // 验证token并设置用户信息到请求中
            String username = jwtUtil.getUsernameFromToken(token);
            // 这里可以将用户信息设置到请求中,以便后续使用
            // request.setAttribute("user", userService.findByUsername(username));

            return true;
        }

        // 没有token或token格式错误,拦截请求
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        return false;
    }
}

配置拦截器

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    private final JwtUtil jwtUtil;

    public WebMvcConfig(JwtUtil jwtUtil) {
        this.jwtUtil = jwtUtil;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor())
                .addPathPatterns("/api/**"); // 配置需要拦截的路径
    }

    @Bean
    public JwtInterceptor jwtInterceptor() {
        return new JwtInterceptor(jwtUtil);
    }
}

编写控制器和页面

控制器
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class ApiController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, 受保护的API!";
    }
}
页面
<!-- index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Spring Boot JWT 演示/title>
</head>
<body>
    <h1>Spring Boot JWT 演示</h1>
    <button onclick="callSecuredApi()">调用受保护的API</button>

    <script>
        function callSecuredApi() {
            fetch('/api/hello', {
                method: 'GET',
                headers: {
                    'Authorization': 'Bearer JWT令牌'
                }
            })
            .then(response => response.text())
            .then(data => alert(data))
            .catch(error => console.error('Error:', error));
        }
    </script>
</body>
</html>

在上述代码中,需要替换以下部分:

  • your-secret-key:在 application.properties 中配置的 JWT 密钥。

  • your-jwt-token:实际生成的 JWT Token。

请注意,这只是一个简单的示例,实际项目中可能需要根据具体需求进行更复杂的配置和处理。

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring BootSpring Security可以很好地结合使用实现RESTful API的认证。而JWT(JSON Web Token)是一种用于认证和授权的安全传输方式。 要在Spring Boot实现JWT认证,可以遵循以下步骤: 1. 添加依赖:在`pom.xml`文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> ``` 2. 创建JWT工具类:创建一个JWT工具类来生成和解析JWT。可以使用JJWT库来简化这个过程。 3. 创建认证过滤器:创建一个继承自`OncePerRequestFilter`的认证过滤器,在该过滤器中检查请求中的JWT,并进行认证。 4. 配置Spring Security:将认证过滤器添加到Spring Security的配置中,以便在每个请求到达之前进行JWT认证。 5. 创建登录接口:创建一个登录接口,用于验证用户的身份并生成JWT。 这是一个简单的示例代码,说明如何在Spring Boot实现JWT认证: ```java // JWT工具类 public class JwtUtils { private static final String SECRET_KEY = "your-secret-key"; private static final long EXPIRATION_TIME = 864_000_000; // 10天 public static String generateToken(Authentication authentication) { UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal(); Date expirationDate = new Date(System.currentTimeMillis() + EXPIRATION_TIME); return Jwts.builder() .setSubject(userPrincipal.getUsername()) .setIssuedAt(new Date()) .setExpiration(expirationDate) .signWith(SignatureAlgorithm.HS512, SECRET_KEY) .compact(); } public static String getUsernameFromToken(String token) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(token) .getBody() .getSubject(); } public static boolean validateToken(String token) { try { Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token); return true; } catch (SignatureException | MalformedJwtException | ExpiredJwtException | UnsupportedJwtException | IllegalArgumentException e) { return false; } } } // 认证过滤器 public class JwtAuthenticationFilter extends OncePerRequestFilter { @Autowired private UserDetailsService userDetailsService; @Autowired private JwtUtils jwtUtils; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String authorizationHeader = request.getHeader("Authorization"); if (StringUtils.hasText(authorizationHeader) && authorizationHeader.startsWith("Bearer ")) { String token = authorizationHeader.substring(7); if (jwtUtils.validateToken(token)) { String username = jwtUtils.getUsernameFromToken(token); UserDetails userDetails = userDetailsService.loadUserByUsername(username); UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authentication); } } filterChain.doFilter(request, response); } } // Spring Security配置类 @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired private JwtAuthenticationFilter jwtAuthenticationFilter; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/login").permitAll() .anyRequest().authenticated() .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); } } // 登录接口 @RestController public class AuthController { @Autowired private AuthenticationManager authenticationManager; @PostMapping("/login") public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) { Authentication authentication = authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()) ); SecurityContextHolder.getContext().setAuthentication(authentication); String token = JwtUtils.generateToken(authentication); return ResponseEntity.ok(new JwtResponse(token)); } } // 登录请求DTO public class LoginRequest { private String username; private String password; // getters and setters } // JWT响应DTO public class JwtResponse { private String token; // constructor and getter } // 用户详情实现类 @Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired private UserRepository userRepository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = userRepository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("User Not Found with username: " + username)); return UserDetailsImpl.build(user); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值