页面嵌入iframe Cookie丢失问题解决
遇到的问题
自身页面以iframe的形式嵌入三方页面中,双方域名不一致导致自身页面的cookie被某些浏览器拦截无法正常被保存到客户端
解决方案
- 后端将cookie以链接参数的形式带给前端
- 前端在请求接口的时候将cookie放在请求头(这里无法直接在请求头放置Cookie参数,需要使用一个新的参数来放置Cookie)
- 后端使用拦截器获获取请求头中Cookie副本解析后重新放置到Cookie中
后端部分实现示例代码
解析获取Response中的Cookie
// 从Response Header 中的 Set-Cookie解析
for (String cookie : response.getHeaders("Set-Cookie")) {cookie = cookie.split(";")[0];String[] split = cookie.split("=", 2);cookieMap.put(split[0], split[1]);
}
后端拦截器设置设置Coookie
@Component
@Order(1)
public class HeaderCookieFilter implements Filter {private static final Logger log = LoggerFactory.getLogger(HeaderCookieFilter.class);private final String HEADER_COOKIE_KEY = "identityKey";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {try {HttpServletRequestWrapper customRequest = (HttpServletRequestWrapper)request;JSONObject cookieInfo = check(request);//如果校验通过if(cookieInfo!=null) {Cookie[] cookies = new Cookie[cookieInfo.size()];// 修改cookieIterator<String> iterator = cookieInfo.keySet().iterator();for (int i = 0; i < cookieInfo.keySet().size(); i++) {String key = iterator.next();String value = cookieInfo.getString(key);Cookie cookie = new Cookie(key, value);cookies[i] = cookie;}request = new CustomRequest(customRequest, cookies);}}catch (Exception e){log.error("header transfor cookie error",e);}chain.doFilter(request,response);}@Overridepublic void destroy() {}private JSONObject check(ServletRequest request) throws UnsupportedEncodingException {HttpServletRequestWrapper customRequest = (HttpServletRequestWrapper)request;// 不存在identityKey请求头,直接跳过String allCookieStrEncode = customRequest.getHeader(HEADER_COOKIE_KEY);boolean hasHeaderCookie = StringUtils.isNotEmpty(allCookieStrEncode);if(!hasHeaderCookie){return null;}String cookieStr = URLDecoder.decode(allCookieStrEncode, CharEncoding.UTF_8);JSONObject cookieInfo = JSON.parseObject(cookieStr);return cookieInfo;}class CustomRequest extends HttpServletRequestWrapper {Cookie[] cookies;public CustomRequest(HttpServletRequest request, Cookie[] cookies) {super(request);this.cookies = cookies;}@Overridepublic Cookie[] getCookies(){return cookies;}}
}