if (StringUtils.hasText(token) && token.startsWith("Bearer ")) { return token.substring(7); // 去除 "Bearer " 前缀 }这个是干嘛
时间: 2024-04-14 21:31:24 浏览: 180
这段代码是用于在请求中提取 JWT(JSON Web Token)的内容,并去除 JWT 前缀 "Bearer "。
首先,通过调用 `StringUtils.hasText(token)`,判断 `token` 是否为非空且不为纯空格的字符串。
接着,通过调用 `token.startsWith("Bearer ")` 来检查 `token` 是否以 "Bearer " 作为前缀。JWT 的标准格式是以 "Bearer " 作为前缀的,例如 "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."。
如果 `token` 非空且以 "Bearer " 作为前缀,则执行 `token.substring(7)`,即去除前缀 "Bearer ",返回除去前缀后的 JWT 内容。
例如,如果 `token` 是 "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",那么经过这段代码处理后,返回的结果将是 "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",即去除了 "Bearer " 前缀。
这段代码的作用是将请求中包含的 JWT 提取出来,并去除前缀,以便后续进行 JWT 的验证或其他处理。
相关问题
springboot用户登录返回token
好的,你可以尝试使用Spring Security和JWT组合来实现用户登录返回token的功能。
1. 首先,在pom.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. 创建一个配置类,用于配置Spring Security和JWT,例如:
```
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Bean
public JwtAuthenticationFilter authenticationTokenFilterBean() throws Exception {
return new JwtAuthenticationFilter();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/").permitAll()
.antMatchers(HttpMethod.POST, "/api/auth/**").permitAll()
.anyRequest().authenticated();
// Add our custom JWT security filter
http.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
```
3. 创建一个JWT工具类,用于生成和解析token,例如:
```
@Component
public class JwtTokenProvider {
@Value("${jwt.secret}")
private String jwtSecret;
@Value("${jwt.expiration}")
private int jwtExpirationInMs;
public String generateToken(Authentication authentication) {
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
return Jwts.builder()
.setSubject(Long.toString(userPrincipal.getId()))
.setIssuedAt(new Date())
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public Long getUserIdFromJWT(String token) {
Claims claims = Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody();
return Long.parseLong(claims.getSubject());
}
public boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException ex) {
logger.error("Invalid JWT signature");
} catch (MalformedJwtException ex) {
logger.error("Invalid JWT token");
} catch (ExpiredJwtException ex) {
logger.error("Expired JWT token");
} catch (UnsupportedJwtException ex) {
logger.error("Unsupported JWT token");
} catch (IllegalArgumentException ex) {
logger.error("JWT claims string is empty.");
}
return false;
}
}
```
4. 创建一个JWT认证过滤器,用于验证token,例如:
```
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenProvider tokenProvider;
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String jwt = getJwtFromRequest(request);
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
Long userId = tokenProvider.getUserIdFromJWT(jwt);
UserDetails userDetails = customUserDetailsService.loadUserById(userId);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception ex) {
logger.error("Could not set user authentication in security context", ex);
}
filterChain.doFilter(request, response);
}
private String getJwtFromRequest(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7, bearerToken.length());
}
return null;
}
}
```
5. 创建一个控制器,用于处理用户登录请求,例如:
```
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtTokenProvider tokenProvider;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsernameOrEmail(),
loginRequest.getPassword()
)
);
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = tokenProvider.generateToken(authentication);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
}
```
其中,LoginRequest是一个包含用户名和密码的请求对象,JwtAuthenticationResponse是一个包含JWT的响应对象。
6. 最后,在application.yml文件中添加以下配置:
```
jwt:
secret: mySecretKey
expiration: 86400000
```
其中,jwt.secret是用于签名的密钥,jwt.expiration是token的过期时间,以毫秒为单位。
springboot使用token实现登录验证接口
可以使用Spring Security和JWT(JSON Web Token)来实现基于token的登录验证接口。下面是一个简单的示例:
1. 添加依赖
在pom.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.0</version>
</dependency>
```
2. 配置Spring Security
在Spring Boot的配置类中添加以下代码:
```
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public JwtAuthenticationFilter authenticationJwtTokenFilter() {
return new JwtAuthenticationFilter();
}
}
```
这个配置类禁用了CSRF保护,允许所有用户访问“/api/auth/**”接口,其余接口需要进行认证。它还使用“JwtAuthenticationFilter”类来验证token。
3. 实现UserDetailsService
创建一个UserDetailsService的实现类,用于从数据库或其他数据源中获取用户信息。例如:
```
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
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);
}
}
```
这里的“UserDetailsImpl”类是一个自定义的实现了UserDetails接口的类,用于封装用户信息。
4. 实现JwtUtils
创建一个JwtUtils类,用于生成和验证token。例如:
```
@Component
public class JwtUtils {
@Value("${jwt.secret}")
private String jwtSecret;
@Value("${jwt.expirationMs}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();
return Jwts.builder()
.setSubject((userPrincipal.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
public String getUsernameFromJwtToken(String token) {
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
}
}
```
这里的“jwt.secret”和“jwt.expirationMs”分别是用于生成token的密钥和过期时间(以毫秒为单位)。
5. 实现JwtAuthenticationFilter
创建一个JwtAuthenticationFilter类,用于在每个请求上验证token。例如:
```
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
String username = jwtUtils.getUsernameFromJwtToken(jwt);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception e) {
logger.error("Cannot set user authentication: {}", e.getMessage());
}
filterChain.doFilter(request, response);
}
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")) {
return headerAuth.substring(7, headerAuth.length());
}
return null;
}
}
```
这个过滤器将从请求头中获取token,并使用JwtUtils类来验证token。如果token有效,则将用户信息设置为Spring Security的上下文中的认证信息。
6. 创建登录接口
创建一个登录接口,用于验证用户并生成token。例如:
```
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtils jwtUtils;
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
return ResponseEntity.ok(new JwtResponse(jwt));
}
}
```
这个接口将使用AuthenticationManager来验证用户信息,并使用JwtUtils类来生成token。如果验证成功,则返回一个包含token的JwtResponse对象。
7. 测试接口
现在可以测试接口了。使用POST方法向“/api/auth/signin”发送以下JSON数据:
```
{
"username": "your_username",
"password": "your_password"
}
```
如果验证成功,则会返回一个包含token的JSON响应。以后,可以在每个请求中将token作为“Authorization”请求头的值发送。
阅读全文