Spring Boot 集成JWT实现前后端认证的示例代码

下面是详细讲解“Spring Boot集成JWT实现前后端认证的示例代码”的攻略。

什么是JWT

JWT全称为JSON Web Token。它是一种轻量级的身份验证机制,可以用于前后端之间的认证和授权。使用JWT进行认证,可以避免服务端为每个客户端的请求保存会话状态,从而提高服务的可伸缩性。

JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。头部包含了一些元数据,描述了令牌的类型和加密算法等;载荷包含了一些自定义的数据,比如用户的ID等;签名则显示了JWT的完整性,确保令牌没有被篡改。

JWT的优势

使用JWT进行认证比传统的cookie 或session认证具有一些优势:

  1. 无状态性:JWT在完成身份认证之后,不需要保存会话状态。客户端可以在每个请求中传递JWT,由服务端进行验证。因此,服务端的资源需要更少。

  2. 可扩展性:由于JWT是基于自包含的JSON结构,所以可以用于扩展其他数据。

  3. 安全性:JWT使用签名来验证令牌的完整性,防止令牌被篡改。此外,可以使用SSL/TLS来保护令牌。

现在我们开始来讲解如何在Spring Boot中集成JWT实现前后端认证。

步骤一:引入依赖

在pom.xml文件中加入以下依赖:

<!--JWT令牌实现-->
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

步骤二:添加JWT的配置类

在Spring Boot项目中添加JWT的配置类,其中包括:

  1. 生成JWT的方法

  2. 解析JWT的方法

  3. 配置JWT的一些参数

@Configuration
public class JwtConfig {

  // 生成JWT的方法
  public static String createToken(Map<String, Object> claims, String subject) {
    long nowMillis = System.currentTimeMillis();
    Date now = new Date(nowMillis);

    JwtBuilder builder = Jwts.builder()
        .setClaims(claims)
        .setSubject(subject)
        .setIssuedAt(now)
        .signWith(SignatureAlgorithm.HS256, "secret");

    long expMillis = nowMillis + 120 * 60 * 1000; // 2小时有效期
    Date exp = new Date(expMillis);
    builder.setExpiration(exp);

    return builder.compact();
  }

  // 解析JWT的方法
  public static Claims parseToken(String token) {
    try {
      return Jwts.parser()
          .setSigningKey("secret")
          .parseClaimsJws(token)
          .getBody();
    } catch (Exception e) {
      return null;
    }
  }

  // 配置JWT参数
  @Bean
  public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setSigningKey("secret");
    return converter;
  }

  @Bean
  public JwtTokenStore jwtTokenStore() {
    return new JwtTokenStore(jwtAccessTokenConverter());
  }

  @Bean
  public TokenEnhancer jwtTokenEnhancer() {
    return new JwtTokenEnhancer();
  }

  // JWT token增加自定义属性
  class JwtTokenEnhancer implements TokenEnhancer {
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
      Map<String, Object> info = new HashMap<>();
      // 添加自定义属性,如用户ID等
      info.put("user_id", 1);
      ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
      return accessToken;
    }
  }
}

步骤三:配置Spring Security

加入以下配置类配置Spring Security。其中包括了继承WebSecurityConfigurerAdapter的指定JWT的认证方式,还包括了继承AuthorizationServerConfigurerAdapter的认证授权方式。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter
        implements AuthorizationServerConfigurer {

  @Autowired
  private AuthenticationManager authenticationManager;

  @Autowired
  private JwtTokenEnhancer jwtTokenEnhancer;

  @Autowired
  private JwtConfig jwtConfig;

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.csrf().disable()
        .exceptionHandling()
        .and()
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests().anyRequest().authenticated()
        .and()
        .apply(new JwtConfigurer(jwtConfig, jwtTokenEnhancer));
  }

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    String secret = "{noop}secret";
    clients.inMemory()
        .withClient("client")
        .secret(secret)
        .scopes("read", "write")
        .authorizedGrantTypes("password", "refresh_token")
        .accessTokenValiditySeconds(3600)
        .refreshTokenValiditySeconds(7200)
        .and()
        .withClient("webapp")
        .secret(secret)
        .scopes("trust")
        .authorizedGrantTypes("implicit")
        .accessTokenValiditySeconds(3600);
  }

  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
    TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
    enhancerChain.setTokenEnhancers(Arrays.asList(jwtTokenEnhancer, jwtConfig.jwtAccessTokenConverter()));

    endpoints.authenticationManager(authenticationManager)
        .tokenStore(jwtConfig.jwtTokenStore())
        .tokenEnhancer(enhancerChain);
  }

  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
        .withUser("user").password("{noop}password").roles("USER");
  }
}

示例一:生成JWT

下面是一个示例代码,用于在用户登录时生成一个JWT:

// 生成JWT
Map<String, Object> claims = new HashMap<>();
claims.put("sub", "user"); // 用户名等可定义的声明
String token = JwtConfig.createToken(claims, "user");

在这个示例中,生成JWT时传入了一个Map类型的claims,用于定义一些自定义的数据,比如用户名等。同时,在setExpiration中指定了JWT的过期时间为2小时。

示例二:解析JWT

下面是一个示例代码,用于在Spring Boot应用中解析JWT:

// 解析JWT
String token = "Bearer xxxx"; // 从Authorization头中提取出token
Claims claims = JwtConfig.parseToken(token);
if (claims != null) {
    String username = claims.getSubject();
    // todo: 验证用户凭据
} else {
    // todo: token无效
}

在这个示例中,解析JWT时调用了JwtConfig类中的parseToken方法,传入了从Authorization头中提取出的token。在parseToken方法中,使用Jwts.parser()解析JWT,并使用setSigningKey("secret")方法指定了密钥为secret。如果解析成功,则可以获得一些自定义的数据,比如用户名等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot 集成JWT实现前后端认证的示例代码 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 分析python动态规划的递归、非递归实现

    针对“分析Python动态规划的递归、非递归实现”这个主题,我将分为以下几个部分进行完整的讲解。 1. 什么是动态规划 动态规划(Dynamic Programming)是一种通过把原问题分解为相对简单的子问题的方式,以递推的方式求解复杂问题的技术。在动态规划中,我们通常会用到“备忘录”或“DP表”来记录以前求解过的值,从而避免重复计算,提高程序效率。 动态…

    Java 2023年5月26日
    00
  • Spring Data JPA 注解Entity关联关系使用详解

    Spring Data JPA是在JPA规范基础上进行了扩展的一种Persistence Framework。在Spring Data JPA中,我们需要使用注解来描述实体类之间的关系。下面,我们将详细讲解“Spring Data JPA 注解Entity关联关系使用详解”的完整攻略。 一、@OneToOne 注解 @OneToOne注解表示一对一关系,常见…

    Java 2023年5月20日
    00
  • 解决表单post,get到springMVC后台乱码的问题

    解决表单post,get到springMVC后台乱码的问题,可以分为以下几个步骤: 1.设置字符编码过滤器 在web.xml配置文件中添加字符编码过滤器,用于处理所有请求的字符编码。 <filter> <filter-name>encodingFilter</filter-name> <filter-class&gt…

    Java 2023年6月16日
    00
  • javaweb前端向后端传值的几种方式总结(附代码)

    以下是对“javaweb前端向后端传值的几种方式总结(附代码)”的详细讲解攻略。 前言 在Web开发中,前端页面需要向后端服务器传递数据以完成后续逻辑的处理,而后端需要获取前端传递的数据进行处理并返回相应的结果。在这个过程中,前后端数据传递是非常重要的,因此准确地传递和获取数据是保证Web应用程序正常运行的基础。接下来,我们将介绍JavaWeb前端向后端传值…

    Java 2023年6月15日
    00
  • Spring AOP结合注解实现接口层操作日志记录

    注解可以方便快捷地给方法或类加上标记,用于识别它们的作用。在Spring AOP中,我们可以通过在方法上使用注解来实现操作日志记录。本文将介绍如何使用Spring AOP结合注解实现接口层操作日志记录。 添加依赖 在pom.xml文件中添加以下依赖: <dependency> <groupId>org.springframework.…

    Java 2023年6月15日
    00
  • 创建一个Java的不可变对象

    创建一个Java的不可变对象,需要经过以下步骤: 1. 声明类为final 为了防止子类继承和重写类中的方法,将类声明为final。 2. 声明所有的属性为私有的final类型 使用final类型声明属性,并且将其设为私有属性,这样无法修改。 public final class ImmutableObject { private final int age…

    Java 2023年5月26日
    00
  • JavaScript ES6的新特性使用新方法定义Class

    关于JavaScript ES6的新特性中使用新方法定义Class的完整攻略,本文将对其进行详细分析和阐述。 什么是Class? 在ES6之前,在JavaScript中定义对象通常使用函数。然而,ES6引入了一个新的类概念,使得定义对象变得更加简单和可读性更强。一个类可以看作是一个对象的蓝图,可以用来创建一组拥有相同属性和方法的对象。 使用新方法定义Clas…

    Java 2023年5月23日
    00
  • Java程序单实例运行的简单实现

    Java程序单实例运行的简单实现 在某些情况下,我们需要保证Java程序只能运行一个实例,这就需要实现Java程序单实例运行的功能。下面是实现Java程序单实例运行的简单攻略: 1. 使用文件锁机制 使用文件锁机制实现Java程序单实例运行的方法是:在程序启动时,创建一个文件并加锁,如果文件已经被锁住,就说明已经有一个实例在运行,程序就要直接退出。下面是示例…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部