I was making a website using Apache Tomcat.
At first, I used an IP adress as both the webpages' address and the apis' address, there was no problem with the setting of Cookies. When I was signing in, http://A.B.C.D:8080/api/signin
set a cookie like sessdata=XXX
, and requests sent by http://A.B.C.D:8080/default.js
could get login status properly.
But today when I changed the webpages' address into https://www.example.top/
(using cloudflare and vercel) and the apis' address into https://api.example.top/
(using nat), I found out that the sign in function couldn't work properly. It worked like that:
http://www.example.com/signin.js
sent a request to https://api.example.top/api/signin
,
https://api.example.top/api/signin
responded with a ```set-cookie`` header:
sessdata=XXX;
I have also tried:
sessdata=XXX; Domain=example.top; Path=/
sessdata=XXX; Domain=api.example.top; Path=/
sessdata=XXX; Domain=www.example.top; Path=/
sessdata=XXX; Max-Age=2147483647; Expires=Tue, 08-Aug-2090 08:08:00 GMT; Domain=example.top; Path=/
Although it did set the cookies, the other JS scripts don't bring the cookies when they send requests to the api, and I can't find the cookie on my browser either.
I have also manually added the cookie at api.example.top
, it worked when I send requests to the API directly, but it didn't work when using JS scripts.
Here are my codes.
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json");
PrintWriter out = response.getWriter();
User verifying = UserGetter.getUserByMail(new String(request.getParameter("mail").getBytes("ISO8859-1"),"UTF-8"));
if(verifying.uid==-1) {
out.println("{\"code\":1}");
} else if(verifying.pword_md5.contentEquals(stringToMD5(new String(request.getParameter("password").getBytes("ISO8859-1"),"UTF-8")))) {
Cookie session = new Cookie("sessdata",SessionBind.newBinding(verifying.uid));
session.setDomain("example.top");
session.setPath("/");
session.setMaxAge(Integer.MAX_VALUE);
session.setSecure(false);
response.addCookie(session);
out.println("{\"code\":0}");
} else {
out.println("{\"code\":2}");
}
}
function signin(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
switch(JSON.parse(this.responseText).code){
case 0:
location.href = "https://www.example.top/signinSuccess.html"
break;
case 1:
alert("This email doesn't exist")
break;
case 2:
alert("Incorrect email or password")
}
}
};
xhttp.open("POST", "https://api.example.top/api/signin", true);
xhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhttp.send("password=" document.getElementById("i2").value "&mail=" document.getElementById("i1").value);
}
CodePudding user response:
I am by no means a front-end developer nor a vercel expert. But you might just need to ensure the withCredentials
flag is set on your XHR request object:
see: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
Description:
The XMLHttpRequest.withCredentials property is a boolean value that indicates whether or not cross-site Access-Control requests should be made using credentials such as cookies, authorization headers or TLS client certificates. Setting withCredentials has no effect on same-site requests.