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日

相关文章

  • 12种最常用的网页编程语言简介(值得收藏)

    首先,我们需要了解网页编程语言的概念和作用。网页编程语言指的是网站开发者使用的语言,用于构建网站的前端和后端部分。网页编程语言可以分成前端语言和后端语言两种。前端语言用于网站的外观和用户交互,后端语言用于网站的数据处理和服务器与数据库等操作。本文将介绍12种最常用的网页编程语言,分别为HTML、CSS、JavaScript、PHP、Python、Ruby、J…

    Java 2023年6月15日
    00
  • Java访问者设计模式详细讲解

    Java访问者设计模式详细讲解 什么是访问者设计模式? 访问者设计模式是一种行为型设计模式,它允许你将对象元素操作与其所在的对象分离开来,并将其封装在另一个对象中。通过这种方式,我们可以在不改变被访问对象的类的前提下,增加新的功能操作。访问者模式在实际应用中非常常见,例如在编译器中,AST(抽象语法树)节点经常会被访问者模式处理。 访问者设计模式的结构 Vi…

    Java 2023年5月26日
    00
  • java的几种定时器的具体使用(4种)

    下面我将详细讲解Java中几种定时器的具体使用。 一、定时器概述 定时器,也称为计时器,是一种可以定期、周期性执行任务的工具。在Java语言中,我们可以使用JDK提供的Timer类或ScheduledExecutorService接口来实现定时任务。 二、Timer类 Timer类提供了一种调度机制,允许我们在指定的时间点执行任务,并支持重复执行任务。 1.…

    Java 2023年5月20日
    00
  • 解析Java异步之call future

    解析Java异步之call future 在Java中,Future是JDK5中新增加的一个接口,可以用于异步调用方法,也就是说在调用Future的get方法时会阻塞,直到异步调用结束并返回结果。下面是一些详细步骤和示例说明。 1. 创建线程池 Java中的Future可以通过ExecutorService的submit方法来实现异步调用。因此我们需要先创建…

    Java 2023年5月26日
    00
  • SpringMVC上传图片与访问

    SpringMVC上传图片与访问攻略 SpringMVC是一个非常流行的Java Web框架,它提供了很多方便的功能,包括文件上传和图片访问。在本文中,我们将详细讲解如何在SpringMVC中上传图片并访问它们。 上传图片 在Web应用程序中,文件上传是一个非常常见的需求。SpringMVC提供了很多方便的方式来处理文件上传,包括使用MultipartFil…

    Java 2023年5月18日
    00
  • MyBatis如何实现流式查询的示例代码

    流式查询是MyBatis中常用的一种查询方式,能够在处理大量数据时提高查询效率。以下是详细的 MyBatis 如何实现流式查询的攻略,包括两条示例代码: 1. 流式查询 流式查询被称为“游标”查询,是基于 JDBC 游标实现的。它的实现方式是通过一次读取一批数据,然后处理它们,最后再继续读取下一批数据。这样可以避免一次性读取所有匹配数据所带来的内存开销和响应…

    Java 2023年5月19日
    00
  • springboot集成kafka消费手动启动停止操作

    下面将详细讲解如何在Spring Boot 项目中集成 Kafka 消费者,并实现手动启动、停止操作。 步骤一:添加Kafka依赖 在 maven 的 pom 文件中添加 Kafka 相关依赖: <dependency> <groupId>org.springframework.kafka</groupId> <ar…

    Java 2023年5月20日
    00
  • 一篇超详细的Spring Boot对jdbc支持的文章

    下面是我对这个主题的完整攻略: 一、简介 在介绍 Spring Boot 对 JDBC 支持的同时,我们需要先了解 JDBC 是什么。JDBC (Java DataBase Connectivity) 是 Java 语言中操作关系型数据库的 API。Spring Boot 建立在 Spring 框架的基础之上,因此 Spring Boot 是通过 Sprin…

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