-
scenario
Third party platform need embedded in our management page, but do not want to separate log in our system, so by our silent land by a default password is redirect to third party need to embed the page, so you can through the backend interface call vouchers to be included in the cookie (proof of our interface information on cookies, Validation on request).
-
The problem
In the actual development of Chrome browser under the implementation of the redirection of the page can not obtain cookies.
-
The implementation process
The process is as follows: 1. Create two projects as our platform (Project A) and A third party platform (Project B). 2. Project A contains only one index. HTML page, and internally nested project B pages with iframe. Sample:
<iframe src="http://localhost:8081/third/logon/login? param=eyJhY2NvdW50IjoiYWRtaW4iLCJwYXNzd29yZCI6InF3ZTEyMyIsInJvbGVDZCI6InN5c3RlbSIsInNvdXJjZSI6IjEifQ==" style="width: 100%; height: 1000px"> </iframe>Copy the code
This is the address of a redirected interface. The parameter is encrypted information. 3. Redirect to the projecet A display page through the Projecet A interface.
Code for the back end:
public void login(ThirdLoginCrmLoginRequest request, HttpServletResponse response) throws the Exception {/ / landing simulation JSONObject result. = RestTemplateUtils postForEntity (loginUrl, initLoginParam(request)); If (result.getINTEGER ("code") == 200) {// Response sets the cookie, ResponseCookie cookie = ResponseCookie.from("tk", Result.getjsonobject ("properties").getString("accessToken")) // key & value. HttpOnly (true) // Disallow js from reading.path("/") // path .maxage (3600 * 24 * 30) // 1 hour expired.build(); // Set Cookie Header Response.setheader (HttpHeaders.SET_COOKIE, cookie.tostring ()); ThirdLoginCrmEnum source = ThirdLoginCrmEnum.getWithSource(request.getSource()); Response. sendRedirect(source == null? ThirdLoginCrmEnum.ThirdRedirectCommon.domain: source.getRedirectUrl(request)); } else { response.sendRedirect(ThirdLoginCrmEnum.ThirdRedirectCommon.domain); }}Copy the code
Here we are setting cookies and Response.sendreDirect. Other business code can be ignored. In theory, I set cookies in the interface of Project A, so the front-end page under the same domain name is also applicable.
What are the facts?
Earlier I said that Chrome(version number :90.0.4430.93) is currently known to be invalid. In real development, the result may be different depending on the browser or version.
Redirecting the interface returns:
As you can see from the returned image, the Response header attempts to set the cookie information. Here’s a look at the sameSite properties I set for testing. This is not normally displayed, and the browser default samesite property is Lax. Those who are interested can find out for themselves. Portal: The sameSite property of the cookie carefully sees a “warning” flag at the end of the set-cookie. The content of the logo is:
This Set-Cookie was blocked because it had the “SameSite=Lax” attribute but come from a cross-site response which was not the response to a top-level navigation
This set-cookie is blocked because it has the “SameSite = Lax” property, but comes from a cross-site response, not a response to top-level navigation
Simply put, a cross-domain request has occurred, but the browser’s default SameSite=Lax does not support cross-domain cookies. Therefore, setting the cookie failed. See the portal above for details.
Display page request information under the same domain name:
Redirected to the page, the request header content does not have cookie information, so the request within the page can not be requested normally.
With that in mind, change the cookie Settings in the back-end code.
ResponseCookie cookie = ResponseCookie.from("tk", Result.getjsonobject ("properties").getString("accessToken")) // key & value. HttpOnly (true) // Disallow js from reading.path("/") // path .maxAge(3600 * 24 * 30) // 1 hour to expire.samesite ("None").Secure (true).build();Copy the code
Set up sameSite and Secure.
SameSite is set to None, and cookies will be sent in all contexts, that is, across domains. The secure attribute must be used together. The value must be set to true and only HTTPS is supported.
After processing, look at the redirected display page request header:
Cookie information already exists. Problem solved.
Not this way, of course. The same effect can be achieved by setting the browser. But I won’t worry about it here, because you can’t ask the user to set it up.