The problem that the session cannot be obtained normally due to the separation of front-end and back-end pages

       Solution to cross-domain problems and session loss caused by separation of front-end and back-end pages

New students, please read this new article. This article is no longer applicable:   Analysis of the repeated jump login problem in the new version of Chrome browser

 A few days ago, I encountered a problem that took me a long time to find due to my lack of experience. It is the java server interface I wrote on my computer virtual machine. When logging in and checking the login interface, the session is used to store user data. When the html is placed in my project, the session value can be obtained very well. , but when the html is placed on the front-end staff's own computer, the session cannot obtain the corresponding value.

After searching online, I found out that this is a problem caused by the separation of front-end and back-end pages. Many netizens have already said very good specific solutions. For specific solutions, you can see here the front-end and back-end separation project, which supports cross-domain and the session is not lost_the session is not lost when deployed in different locations before and after_woshiyeguiren's blog-CSDN blog .

Then let me make an advertisement: It has been almost two weeks since I first unblocked Java, and I have made a pbr material library for my company. Interested friends can take a look and click to open the link

2018.10.24 added:

Although I have encountered this pitfall when I first came into contact with Java, I still did not expect that it would take so long to encounter the same problem later. I will provide detailed supplements on how to deal with several situations.

Cross-domain problems are very common in web development. When deploying our project, for example, if we put the front-end code on one server (oss) and the back-end code on another server, there will be cross-domain problems without any forwarding or configuration between the two. domain issues. Secondly, due to the use of interface development, the front-end code will inevitably be placed on the computer of the front-end staff, and the back-end code will be placed on the computer of the back-end staff. This will also cause cross-domain problems. However, when doing interface docking, allowing front-end personnel to directly access the computers of back-end personnel, problems can be clearly reported to both parties. Direct modification in this way should be a very fast development process. Therefore, we do not consider whether there will be cross-domain problems when deployed to online servers. We all need to solve the cross-domain problems caused by the second situation and the problem of session loss.

1: Background processing method of native java writing method

①: In the background, we write a unified request return interface and set the header. Called uniformly when requesting data is returned

  // 返回json字符串数据
    void post_jsondata(HttpServletRequest request, HttpServletResponse response, JSONObject output)
            throws ServletException, IOException {
        response.setContentType("text/html");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");//是否支持跨域
        response.setHeader("Access-Control-Allow-Methods", "GET,POST");
        PrintWriter out = response.getWriter();
        out.println(output.toString());
        out.flush();
        out.close();
        // super.doPost(request, response);
    }

②: In the front-end page code, we include the attribute xhrFields: {withCredentials: true} in the ajax request, which means providing cookie information.

<button id="buttom2b">用户端-测试按钮2</button>
    <script type="text/javascript">
        $("#buttom2b").click(function() {
            var shit = {
                    store_id:2
            };
            $.ajax({
                type : 'post',
                url : "http://192.168.0.15:8080/carplatform/User/test2",
                dataType : 'json',
                contentType : "application/json;charset=UTF-8",
                data : JSON.stringify(shit),
                xhrFields: {withCredentials: true},
                success : function(xxx) {
                console.log(xxx);
                }
            });
        });
    </script>

2: Java background processing method with framework (ssm)
     

We create an html file on the desktop to access our back-end java code and simulate the separation of the front and rear pages, which will cause the problem of session loss.

When I encountered this problem, the modification process was as follows:
①: Use ajax for direct access without making any settings, and an error 403 Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403. Obviously it is cross-domain and the backend rejected the request.
②: We solve the cross-domain problem by adding the annotation "@CrossOrigin(origins = "*", maxAge = 3600)" to the backend contorller to allow all requests, so that the backend methods can be accessed.
③: But a new problem arises. Every time we request, as long as request.getSession() is called in the background (or the session is passed directly as a parameter in springmvc), a new session will be generated.
④: When we write in native java, the front-end ajax has the attribute xhrFields: {withCredentials: true}, and we also add it. One test reported an error, and it was probably a cross-domain issue. emmmmm, isn’t cross-domain already allowed? What the hell is this? After checking the information, it roughly says that the annotation "@CrossOrigin(origins = "*", maxAge = 3600)" is only applicable to get requests.
⑤: Our native Java can solve it, so it is definitely possible to replace it with a framework. After searching for information, we found that what we need is to set the header of the response every time. According to what is said online, we can intercept each request and set it before entering the controller, then the problem will definitely be solved.

Specific writing method: ① Create a new interceptor class to intercept and set the response header for each request. ②: Register this interceptor in webxml ③: Pay attention to the front-end ajax plus "xhrFields: {withCredentials: true}"

拦截器类///
package com.xunshi.TimerEvent;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @author liangpeng
 * @ClassName: AuthorityInterceptor拦截器,拦截每次请求
 * @Description: 前后端分离导致session不一致问题
 * @date 2018年10月18日  
 */
public class AuthorityInterceptor implements Filter {
    @Override
    public void destroy() {
    }
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        response.setContentType("textml;charset=UTF-8");
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "0");
        response.setHeader("Access-Control-Allow-Headers",
                "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("XDomainRequestAllowed", "1");
        chain.doFilter(req, res);
    }
    @Override
    public void init(FilterConfig arg0) throws ServletException {
    }
}
///webxml配置,添加注册///
  <!--自定义拦截器,每次请求拦截,设置session跨域以及维持session配置  -->
  <filter>
       <filter-name>AuthorityInterceptor</filter-name>
       <filter-class>com.xunshi.TimerEvent.AuthorityInterceptor</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>AuthorityInterceptor</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>

Three: Front-end processing of WeChat applet session issues, and modification of back-end code

The above two are for basic ajax requests. For WeChat mini programs, since mini programs cannot use ajax to make http requests, the cross-domain session problem handling of WeChat mini programs is a little different.
The specific method is: ① The backend returns the mini program sessionid (preferably encrypted) after the first mini program access, and there is no need to configure anything else. ②: Each time the mini program requests a sessionid, the Java background will automatically determine which client it is based on the sessionid and find the corresponding session.
  

       wx.request({
            url: getApp().globalData.url + 'User/ShowOneCar/' + res.data.car_id,
            header: { "Cookie": "JSESSIONID=" + wx.getStorageSync("sessionID") },//带上这句话,sessionID是登陆后后端返回存在缓存里面的
            success: function (rr) {
              console.log(rr);
              if (rr.data.state) {
                that.setData({
                  carinfo: rr.data.thiscar
                });
              }
            }
          })

For the session problem of the mini program, there is no need to create an interceptor for setting up in the background. It is a bit confusing that ajax does not work.
However, there are more or less problems with using sessions to store data, including issues with security and server pressure. But currently I don’t know of any simpler way to store user login status, so let’s use it first.

Guess you like

Origin blog.csdn.net/qq_22824481/article/details/81004051