该问题在acwing springboot的项目中遇到。
文章目录:
目录
1.重写JwtAuthenticationTokenFilter:
2.vue中ajax的如何写get请求可以将headers传到后端
问题描述:
最近springboot 6.0做了更新,之前通过写JwtAuthenticationTokenFilter来过滤用户请求,该类继承了OncePerRequestFilter。版本更新之前OncePerRequestFilter的参数类型为javax包下的HttpServletRequest、HttpServletResponse、FilterChain。更新后参数类型变为jakarta包下的数据类型。所以JwtAuthenticationTokenFilter需要重写,并且产生了前后端分离时,ajax的get请求无法将headers传到后端。
问题解决:
1.重写JwtAuthenticationTokenFilter:
import com.kob.backen.mapper.UserMapper;
import com.kob.backen.pojo.User;
import com.kob.backen.service.impl.utils.UserDetailsImpl;
import com.kob.backen.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletException;
import jakarta.servlet.FilterChain;
import java.io.IOException;
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private UserMapper userMapper;
@Override
protected void doFilterInternal(@NotNull HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws jakarta.servlet.ServletException, IOException {
System.out.println(request);
System.out.println(request.getMethod());
System.out.println(request.getHeader("Authorization"));
String token = request.getHeader("Authorization"); // 从请求头中获取名为"Authorization"的字段
if (!StringUtils.hasText(token) || !token.startsWith("Bearer ")) { // 这个字段应该包含一个以"Bearer "开头的JWT
filterChain.doFilter(request, response); // 将请求传递给下一个过滤器或处理器
return;
}
token = token.substring(7); // 跳过"Bearer "共7个字符
String userid;
try {
Claims claims = JwtUtil.parseJWT(token); // 解析JWT,获取JWT的载荷
userid = claims.getSubject(); // 从载荷中获取"subject",这个"subject"应该是用户ID
} catch (Exception e) {
throw new RuntimeException(e);
}
User user = userMapper.selectById(Integer.parseInt(userid)); // 查询数据库获取用户信息
if (user == null) {
throw new RuntimeException("用户未登录");
}
UserDetailsImpl loginUser = new UserDetailsImpl(user);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(loginUser, null, null);
SecurityContextHolder.getContext().setAuthentication(authenticationToken); // 将其设置到Spring Security的上下文中
filterChain.doFilter(request, response); // 将请求传递给下一个过滤器或处理器
}
}
2.vue中ajax的如何写get请求可以将headers传到后端
$.ajax({
url:"http://127.0.0.1:3000/user/account/info/", //请求的地址
type:"get",
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', 'Bearer ' + '你的token');
//写入的headers参数,如果有多个参数该语句写多个.
},
success(resp){
console.log(resp);
},
error(resp){
console.log(resp);
}
});
通过上面两步问题就可以解决了。
个人见解:
我查了大量相关问题,大多数将后端读不到headers归为ajax先发送预请求,需要将OPTION请求跳过,但通过调试程序可以看到请求的method一直为GET。
新版本我认为是对请求提出了特定的要求需要在打开连接(open())后且发送send()之前调用setRequestHeader方法。setRequestHeader的简单示例为:
let xhr = new XMLHttpRequest();
xhr.open('GET', 'your_url', true);
xhr.setRequestHeader('header_name', 'header_value');
xhr.send();
直接调用这个类也可以将headers传到后端。