SpringBoot框架集成token实现登录校验功能

下面是详细讲解SpringBoot框架集成token实现登录校验功能的完整攻略。

一、什么是Token

在Web开发中,服务端不能直接拿到客户端的登录状态,而客户端又需要传递一些数据,这时就需要一种机制来帮助服务端识别客户端的身份,这种机制就是Token。

Token是一种令牌,本质上就是一个字符串,客户端在登录时通过身份验证后,服务端会返回给客户端一个Token,每次客户端请求时都会携带这个Token,服务端通过验证Token来确定客户端的身份。

二、实现步骤

1. 引入依赖

在pom.xml中引入SpringBoot的web和security依赖,以及生成Token所必须的JWT依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Security -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</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>

2. 配置拦截器

通过实现HandlerInterceptor接口,实现Token校验的拦截器。

@Component
public class AuthenticationInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取请求头中的Token
        String token = request.getHeader("Authorization");
        if (StringUtils.isNotBlank(token)) {
            try {
                // 验证Token是否正确
                Jwts.parser().setSigningKey("MyJwtSecret").parseClaimsJws(token.replace("Bearer ", ""));
                return true;
            } catch (Exception e) {
                throw new BusinessException("无效的Token");
            }
        } else {
            throw new BusinessException("缺少Token");
        }
    }
}

3. 配置安全认证

WebSecurityConfigurerAdapter中配置UserDetailsServicePasswordEncoder,实现安全认证。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login").permitAll()
                .antMatchers(HttpMethod.POST, "/user").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilterBefore(tokenAuthenticationFilter(), BasicAuthenticationFilter.class);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public TokenAuthenticationFilter tokenAuthenticationFilter() {
        return new TokenAuthenticationFilter();
    }

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

4. 配置Token生成

在登录成功后,通过JWT生成Token,并返回给前端。

@Service
public class AuthServiceImpl implements AuthService {
    @Override
    public String login(UserDto userDto) {
        UserDetails userDetails = userDetailsService.loadUserByUsername(userDto.getUsername());
        if (userDetails == null || !passwordEncoder.matches(userDto.getPassword(), userDetails.getPassword())) {
            throw new BusinessException("用户名或密码不正确");
        }
        String token = Jwts.builder()
                .setSubject(userDetails.getUsername())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 24 * 1000))
                .signWith(SignatureAlgorithm.HS512, "MyJwtSecret")
                .compact();
        return "Bearer " + token;
    }
}

5. 测试接口

编写测试接口,通过Token校验保护接口的安全。

@RestController
public class TestController {
    @GetMapping("/test")
    public String test() {
        return "Hello, World!";
    }

    @PostMapping("/user")
    public String saveUser() {
        return "Save user";
    }
}

三、示例应用

下面是两个简单的示例应用:

示例1:登录成功生成Token

POST /login HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{"username": "admin", "password": "admin"}
HTTP/1.1 200 OK
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTYyNDUyMzk5MCwiZXhwIjoxNjI0NTMwNjAwfQ.VR1HBXrzr6AAUSI3vAhN8v8RNSj3r4GgUCYDoA9BPrLOTOl8BU-L8ap6lhDcE3YlXxDlOqPSuPTv6NQGCWBIhA

示例2:未传递Token校验失败

GET /test HTTP/1.1
Host: localhost:8080
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8

{"code":400,"message":"缺少Token"}

示例3:传递无效Token校验失败

GET /test HTTP/1.1
Host: localhost:8080
Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTYyNDUyMzU1NCwiZXhwIjoxNjI0NTMwMzU0fQ.sVb6XEBVfSzDpvZirq_JYFmm1MXJhcbtzrlLmdeLZ1x-KCcoy8jPKpXGnwCgdzF3n_h_J-bQrIFV7E9cv0yXzw

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8

{"code":400,"message":"无效的Token"}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot框架集成token实现登录校验功能 - Python技术站

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

相关文章

  • java基础之Collection与Collections和Array与Arrays的区别

    Java基础之Collection与Collections和Array与Arrays的区别 在Java中,有些名字相似的类是不同的,有些则是同名类的一个是接口、一个是静态工具类。Collection与Collections以及Array与Arrays就是这样的一个示例。 Collection和Collections Collection是Java的一个接口,…

    Java 2023年5月26日
    00
  • Struts2 $,#,%详解及实例代码

    Struts2 $,#,% 详解及实例代码 引言 在处理 Struts2 代码时,经常可以看到一些用于处理 EL 表达式和字符串的字符,例如 $、#、% 等。这些字符在 Struts2 的开发中可以起到非常关键的作用。本文将介绍以下几个知识点: 关于 $、#、% 三个字符的作用以及使用场景 $ 和 # 在 Struts2 中的区别 $ 和 # 的示例代码 %…

    Java 2023年5月20日
    00
  • Java的Hibernate框架中的组合映射学习教程

    我将为您详细讲解Java的Hibernate框架中的组合映射学习教程的完整攻略。步骤如下: 1. 了解组合映射的概念 组合映射就是将一个实体类中的组合类型的对象映射到数据库中的一张表的一行记录中,这张表中除了组合类型的对象所对应的列之外,还有其他的列。组合映射并不是将组合类型的对象映射成一个单独的表,而是将包含有组合类型对象的实体类映射成一张表,表中主要包含…

    Java 2023年5月31日
    00
  • jsp下显示中文文件名及绝对路径下的图片解决方法

    下面是详细讲解“jsp下显示中文文件名及绝对路径下的图片解决方法”的完整攻略。 问题描述: 在jsp页面中,有时需要显示中文文件名或访问绝对路径下的图片,但这些操作并不是很直接,需要做一些额外的处理。 解决方案: 1. 文件名中文显示 在jsp页面中,如果要显示中文文件名,需要注意两点: 页面编码要设置为UTF-8,否则中文文件名会乱码。 使用URLEnco…

    Java 2023年6月15日
    00
  • 带你入门Java的泛型

    带你入门Java的泛型攻略 什么是泛型? 泛型是Java中一个非常强大的特性,它可以让我们在编程时更加安全和便捷。简单来说,泛型就是一种具有类型参数化能力的编程机制。 Java语言中引入泛型,是为了解决在编译时无法确定类型参数的情况下,对类型检查和类型转换的灵活性问题。 泛型的优点 代码重用:泛型的声明可以与具体类型无关,因此可以使用相同的代码来处理不同类型…

    Java 2023年5月23日
    00
  • java读取wav文件(波形文件)并绘制波形图的方法

    让我来为你详细讲解“java读取wav文件(波形文件)并绘制波形图的方法”的完整攻略。 概述 在Java中读取WAV文件,并绘制波形图的步骤可以分为以下几个步骤: 读取WAV文件的头信息,确定WAV文件的音频参数; 读取WAV文件的音频数据; 将音频数据转换为波形图上的点集; 使用Java图形库绘制波形图。 读取WAV文件头信息 WAV文件的头部信息包含了一…

    Java 2023年5月31日
    00
  • Java中File的实例详解

    Java中File的实例详解 Java中的File类提供了一些方法来操作文件和目录。本文将详细讲解File类的实例用法。 创建一个File实例 要创建一个File实例,可以使用以下构造函数: File(String pathname) 这个构造函数接受一个字符串参数,表示文件的路径。下面是一个简单的例子: File file = new File(&quot…

    Java 2023年6月1日
    00
  • springboot自定义redis-starter的实现

    下面我将详细讲解 Spring Boot 自定义 Redis Starter 的实现过程: 1. 编写 Redis Starter 的核心代码 Spring Boot 自定义 Starter 可以方便用户在项目中引入各种第三方组件。在这里我们需要编写一个 Redis Starter,使得用户可以通过 Spring Boot 自动配置方式来使用 Redis。 …

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