前端在浏览器总报错,且获取请求头中token的值为null
前端请求总是失败说受跨域请求影响,但前后端配置已经没有问题了,如下:
package com.example.shop_manage_sys.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.example.shop_manage_sys.Interceptor.TokenInterceptor;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Autowired
private TokenInterceptor jwtInterceptor;
//cors配置
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // Applies CORS to all paths
.allowedOrigins("http://127.0.0.1:8081", "http://localhost:8081") // List specific allowed origins
.allowedMethods("GET", "POST", "PUT", "DELETE","OPTIONS")
.allowedHeaders("accept", "content-type", "origin", "custom-header","token")
.allowCredentials(true)
.maxAge(3600);
}
//拦截器配置
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/sms/*"); // 排除不需要拦截的路径
}
}
后端获取前端请求头中自定义的token字段时获取到null,这是因为浏览器端会在请求前总发出一次预检请求,后端的拦截器将这种options请求直接放行即可。
示例拦截器代码:
package com.example.shop_manage_sys.Interceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
// import org.springframework.web.servlet.ModelAndView;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
// import java.util.Base64;
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Value("${jwt.secret}")
private String SECRET_KEY;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
// 直接放行预检请求
return true;
}
String token = request.getHeader("token");
if (token != null && !token.isEmpty()) {
try {
// 验证并解析token
Key key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes(StandardCharsets.UTF_8));
Jws<Claims> claimsJws = Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token);
Claims claims = claimsJws.getBody();
request.setAttribute("claims", claims);
return true;
} catch (Exception e) {
handleJwtError(response, "Invalid or expired token.");
return false;
}
} else {
handleJwtError(response, "Token is missing.");
return false;
}
}
private void handleJwtError(HttpServletResponse response, String errorMessage) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
try {
// Wrap the ServletOutputStream in a ServletServerHttpResponse
ServletServerHttpResponse outputMessage = new ServletServerHttpResponse(response);
// Convert the JSON string to an Object
Object jsonContent = "{\"error\": \"" + errorMessage + "\"}";
// Write the JSON content to the output stream
new MappingJackson2HttpMessageConverter().write(jsonContent, MediaType.APPLICATION_JSON, outputMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
// 你可以选择性实现以下方法,但在这个场景下它们可能不是必须的
// @Override
// public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
// // ...
// }
//
// @Override
// public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// // ...
// }
}
原文地址:https://blog.csdn.net/qq_51691526/article/details/140642786
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!