下面是详细讲解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
中配置UserDetailsService
和PasswordEncoder
,实现安全认证。
@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技术站