Java jQueryAjax即使在登录后也会返回401
我有一个jax rs应用程序,其中包含以下资源:Java jQueryAjax即使在登录后也会返回401,java,ajax,jax-rs,session-variables,Java,Ajax,Jax Rs,Session Variables,我有一个jax rs应用程序,其中包含以下资源: @Path("login") public class Login { @Context private HttpServletRequest request; @POST public Response login(@FormParam("username") String username, @FormParam("password") String pass
@Path("login")
public class Login {
@Context
private HttpServletRequest request;
@POST
public Response login(@FormParam("username") String username,
@FormParam("password") String password){
if(isAuthenticated(username,password)) {
HttpSession session = request.getSession();
session.setAttribute("username",username);
return Response.ok().build();
}
return Response.status(401).build();
}
private static boolean isAuthenticated(String userName, String password) {
// code that checks user credentials
}
}
我还将此筛选器应用于所有URL:
public class AuthFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if (servletResponse instanceof HttpServletResponse) {
HttpServletRequest request = (HttpServletRequest) servletRequest;
if(!request.getRequestURI().contains("login")){
HttpSession session = request.getSession();
if(session.getAttribute("username")==null){
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setStatus(401);
return;
}
}
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
现在,我已应用此筛选器以允许跨来源请求:
public class CORSFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if(servletResponse instanceof HttpServletResponse){
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
response.addHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.addHeader("Access-Control-Allow-Headers",
"origin, content-type, accept, authorization");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
我已经通过检查浏览器中请求多个URL时的响应头验证了过滤器的工作原理
使用Postman,我验证了登录是否有效,登录后我可以访问任何资源
但是使用跨域ajax,我使用以下代码发出post请求:
$.post("http://example.com/login",{
username: "ahmad",
password: "ahmad"
})
然后我对一个资源执行另一个ajax,如下所示:
$.ajax({
url: "http://example.com/task",
xhrFields: {
withCredentials: true
}
}).then((data) => {
// do something with data
})
第二个请求返回401 unauthorized,即使我确实登录了,并且在控制台中没有看到任何无访问控制允许源…
消息,只有401 unauthorized
现在,我在第二个请求中检查了AuthFilter
中的session.getAttribute(“用户名”)
,它返回null,就好像会话无效,但它不是
发生了什么事?如何解决这个问题?邮递员为什么工作
编辑
现在我验证了第一个请求的响应中的会话id cookie与第二个请求的cookie中的id不匹配,因此现在我知道了问题所在,但不知道如何解决它
顺便说一下,Chrome63和Firefox58都出现了问题