session Problem of Front-end and Back-end Separation

Posted by psyqosis on Sun, 18 Aug 2019 15:34:17 +0200

[session Problem --- Pit Jumping + Pit Climbing]

session Foundation Points:
Session is session control. The session object stores the properties or configuration information required by a particular user session. When users jump between the web pages of the application, session objects will always exist.
2. The session object is created by the server when the client makes a request to the server.
3. Session state is reserved only in browsers that support cookie s.
[Focus]
(1) session is unique in the same browser.
(2) Sessions are created by servers. Sessions between different servers (ip, domain name, port arbitrarily different) are different, and they do not share session s.
(3) When a session object is created, the server generates a session's unique identity, which is the JSession ID. So the JSession ID is different between different servers.
(4) JSession ID, as the unique identifier of session, is returned to the client in the form of cookie, while it is saved in the form of memory at the server.
[Questions]
(1) Session coverage: When two or more servers are accessed simultaneously on the browser, because different servers do not share sessions and the browser has only one session, the problem of session coverage will arise.
Performance: Jsessoin ID is different each time when accessing server A and B in turn.
For the first time accessing server A in browser, there is no session in server A, then JSession ID_A is generated by A and saved in cookie form.
When switching to ServerB, there is no Session on the B server, and JSession ID_B is generated by B and returned to the client in the form of cookie s. At this time, JSession ID_B will overwrite JSession ID_A.
This triggers a new JSession ID each time, that is, a new session object is generated each time, and the content of the old object is overwritten.
        
(2) Sessions are not shared: As mentioned above, sessions are different when clients access different servers. That is, sessions can not be shared between servers, each has its own unique session.
Performance: In distributed systems, when business is split up, different businesses are treated as a single service, and business interconnection becomes a system. When users jump between different services of the system, they access different servers with different conveniences.
Because sessions store user's identity information and privilege information, if sessions cannot be shared, the function of the whole system will be meaningless. For example, the system may repeatedly remind users to log in.
                
Jumping from a pit
As a back-end whitewash, it is often necessary to touch the logic of the front-end. I often shuttle between front-end and back-end interactions!
In order to test session, I found the code of my front-end teammates and made some modifications to form a small demo with front-end and back-end separation.
Background: Front-end separation and interaction with axios+restful API
        
Pit 1: axios is used on the front end, and cookie s are not carried by default.
Pit 2: Because the front and back end are separated, it must be cross-domain, but cookie s are not cross-domain by default and need to be set up in the back end.
        
Solution: The above two problems can be solved easily. There are a lot of blogs, all of which solve the above problems.
Steps:
1. When axios is introduced into the front end, make a global setting in main.js to allow cookie s to initiate requests.
              

import axios from 'axios'    //Import axios                
axios.defaults.withCredentials = true    //Global settings axios allow access with cookie s                
Vue.prototype.$axios = axios    //Set the Axios global scalar, and then you can access it in the form of this.$axios


                
Or, as a local setting, axios allows cookies to be carried to initiate requests, just add them to requests that need to carry cookies
                    

xhrFields: {                        
    withCredentials: true                    
}


For example:
                  

this.$axios({                        
    xhrFields: {                            
        withCredentials: true                        
    },                        
    method: 'get',                        
    url: 'http://localhost:8080/...',                    
}).then(resposnse=>{                        
    console.log("Verification")                    
})


Back-end assistance: Allow cookie cross-domain access while configuring cross-domain
(1) springboot annotation: Add the following annotations to the startup class:
                

@CrossOrigin(origins = "http://localhost:8082", maxAge = 3600,allowCredentials = "true")


Attention:
Allow Credentials= "true" means that cookie s are allowed to be accessed across domains.
The value of the orgins attribute is the front-end ip + port, which means that requests from the source are allowed to access the server. Because cookie s are configured to be accessed across domains, orgins must not be set to "*" (any source is allowed to access)
                
(2) Custom filter method: (Principle as above)
                
                

@Slf4j
@Configuration
@WebFilter(urlPatterns = "/*", filterName = "crossDomainFilter")
@Order(1)
public class CrossDomainFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        log.info("[Cross Domain Filter ";
		/*
         *  Access-Control-Allow-Origin The response header specifies whether the resources of the response are allowed to be shared with a given origin.
		 *  For requests that do not require credentials, the server uses "*" as a wildcard character, allowing access to resources for all domains.
		 *  You can specify a URI that can access resources.
		 *
		 *  CORS And caching
		 *  If the server does not use "*" but specifies a domain, the return of the server will vary according to the Origin request header in order to indicate to the client.
		 *  Origin must be included in the Vary response header.
		 *  	For example:
		 *  	Access-Control-Allow-Origin: https://developer.mozilla.org
		 *  	Vary: Origin
		 */
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));

		/*
		 *  The request header Access-Control-Request-Method appears in preflight request.
		 *  Used to notify the server which HTTP method will be used in the real request.
		 *  This header is necessary because the method used for preview requests is always OPTIONS, which is different from the method used for actual requests.
		 */
        response.setHeader("Access-Control-Allow-Method", "*");

		/*
		 * The Access-Control-Max-Age This response header represents the return result of preflight request
		 * (That is, the information provided by Access-Control-Allow-Methods and Access-Control-Allow-Headers.
		 *  How long can it be cached
		 */
        response.setHeader("Access-Control-Max-Age", "3600");


		/*
		 *  Response to header Access-Control-Allow-Headers for preflight request
		 *  Lists the header information that will appear in the Acess-Control-Request-Headers field of the formal request
		 *
		 *  Note that the following specific headings are always allowed:
		 *  	Accept, Accept-Language, Content-Language,Content-Type
		 *  	Where Content-Type (only if its value belongs to MIME type application/x-www-form-urlencoded, multipart/form-data or
		 *  	text/plain One of them.
		 *  	These are called simple headers, and you don't have to declare them.
		 */
       // response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        response.setHeader("Access-Control-Allow-Headers", "Authorization,Origin, X-Requested-With, Content-Type, Accept,Access-Token");
        //Origin, X-Requested-With, Content-Type, Accept,Access-Token

		/*
		 * Response header Access-Control-Expose-Headers lists which headers can be exposed as part of the response
		 *
		 * By default, only six simple response headers (simple response headers) can be exposed to the outside world:
		 * Cache-Control
		 * Content-Language
		 * Content-Type
		 * Expires
		 * Last-Modified
		 * Pragma
		 * If you want clients to have access to other headers, you can list them in Access-Control-Expose-Headers.
		 */
        response.setHeader("Access-Control-Expose-Headers", "checkTokenResult");
        //Setting response headers that can be exposed
        response.setHeader("Access-Control-Expose-Headers", "message");


        /*
        * Allow cookie s to cross domains
        * */
        // Indicates whether the response to the request can be exposed to the page. When he returns to true, he can be exposed to Credentials.
        response.setHeader("Access-Control-Allow-Credentials", "true");

		/*Credentials
		 * no-cache: 
		 * 	Before publishing the cache copy, the cache is forced to submit the request to the original server for validation.
		 */
        response.setHeader("Cache-Control", "no-cache");

        // Return the request back to the filter chain
        filterChain.doFilter(servletRequest, servletResponse);
    }
}


                
All right, all these problems have been solved. Do you think it's really over?
        
Pit 3 (my big boss): The above content is the solution to most netizens'problems, but it's not for me. As a back-end whitewash, the cycle of Solving session problems consumes this third step!
I can only say that if you do this step by step, you can already achieve front-end and back-end session access, so I congratulate you.
If sessionId is not the same for continuous visits to the same server, congratulations. You're probably looking for the right person.
            
I want to ask a question: Have you used mock yet?
            
If so, you're the last step to success.
            
What is a demon: mock.js
(mock refreshes the cookie s for each request, resulting in different Session IDs being retrieved each time in the background.)
            
When I saw this sentence, I felt so much that I almost cried, and it took me a whole day or two!
So I immediately annotated the request (mock. js) and the place where the import mock is on the page, and noticed if you introduced mock in main.js! Okay, test, send the request, I succeeded!


Too verbose, leaving no technical tears! How to solve session sharing, the next article will introduce!

Topics: Session axios Vue SpringBoot