The author’s writing skill is still shallow, if there is something wrong, please point out generously, will be grateful
Cookie
1Luo: Grandpa, 322 upstairs is Ma Dongmei's house, right?
2
3Grandpa: What are horses?
4
5Charlotte: Ma Dongmei.
6
7Grandpa: Nothing?
8
9Charlotte: Ma Dongmei.
10
11Grandpa: What did the horse have?
12
13Charlotte: Ok, grandpa, you cool down first.
Copy the code
Before we look at these three concepts, we need to understand that HTTP is a stateless Web server. What is stateless? As in the classic episode of Goodbye Charlotte above, one conversation is finished and the next conversation has no idea what happened in the previous one. If you’re using a Web server just to manage static files, it doesn’t matter who you’re dealing with, just read the files off disk and send them out. However, with the continuous development of the Internet, for example, the shopping cart in e-commerce can only perform a series of actions after remembering the user’s identity. So it’s time for our stateless server to remember something.
So how does a Web server remember something? Since the Web server can’t remember things, we try to remember them externally, which is equivalent to the server putting a little piece of paper on each client. It records some of the information that the server sent back to us. And then the server sees this little piece of paper and knows who we are. So who makes cookies? Cookies are generated by the server. Next, let’s describe the Cookie generation process
- When the browser accesses the server for the first time, the server must not know its identity, so create a unique identity identifier data in the format of
key=value
, into theSet-Cookie
With the response packet sent to the browser. - Browser sees yes
Set-Cookie
The field will later know that this is the identity given by the server, so it will be saved for the next requestkey=value
Value into theCookie
Field to the server. - After receiving the request packet, the server detects that
Cookie
If there is a value in the field, the user can be identified according to this value and then personalized services can be provided.
Next we use code to demonstrate how the server is generated. We build a background server ourselves. Here I use SpringBoot to build, and write the code of SpringMVC as follows.
1@RequestMapping("/testCookies")
2public String cookies(HttpServletResponse response){
3 response.addCookie(new Cookie("testUser"."xxxx"));
4 return "cookies";
5}
Copy the code
After we enter the path of project startup http://localhost:8005/testCookies, then look at the request of hair. You can see in the graph below that the request was sent when we first accessed the server. You can see that the response returned by the server has a set-cookie field. The key=value value inside is the value set in our server.
Then we refresh the page again to see that the Cookie field has been set in the request body and our value has been brought in. So the server can remember our information based on the value in the Cookie.
Now what about a different request? Does Cookie bring it with him? Next we enter the path http://localhost:8005 request. We can see that the Cookie field is still carried over.
So where do browser cookies go? If you’re using Chrome, follow these steps.
- Turn on the computer
Chrome
- In the upper right corner, one click
More and more
Icon – >Set up the
- At the bottom, click
senior
- in
Privacy Settings and security
Below, click Site Settings - In turn, click
Cookie
-> View allCookies and website data
The managed Cookie data can then be searched by domain name. So the browser manages the Cookie for you, and if you switch to Firefox or some other browser, because the Cookie was stored in Chrome, the server gets clouded again, doesn’t know who you are, and it puts a little note on Firefox again.
Parameter Settings in cookies
At this point, you should know that cookies are data that the server trusts the browser to store in the client, and this data usually records key identifying information about the user. Therefore, cookies need to be protected by some other means to prevent leakage or theft, which are the attributes of cookies.
Parameter names | role | Back-end setting method |
---|---|---|
Max-Age | Set the cookie expiration time, in seconds | cookie.setMaxAge(10) |
Domain | Specifies the domain to which the Cookie belongs | cookie.setDomain("") |
Path | Specifies the path to which the Cookie belongs | cookie.setPath(""); |
HttpOnly | Tell the browser that the Cookie can be transmitted only through the browser Http protocol and cannot be accessed by other methods | cookie.setHttpOnly(true) |
Secure | Tells the browser that the Cookie can only be transmitted over Https, or forbidden over Http | cookie.setSecure(true) |
Here I will briefly demonstrate the usage and phenomenon of these parameters.
Path
Set to cookies. SetPath (“/testCookies “), then we visit http://localhost:8005/testCookies, we can see on the left the specified path is the same with us, so in the request header to cookies, Next we go to http://localhost:8005, and we see that there is no Cookie field, which is the Path controlled by Path.
Domain
Set to cookies. SetDomain (” localhost “), then we visit http://localhost:8005/testCookies we found in the image below is cookies on the left side of the field, But we visit http://172.16.42.81:8005/testCookies, see below on the right side of the field can see no cookies. This is the Domain controlled Domain that sends cookies.
I’m not going to show you the next few parameters, so I’m sure you have a little bit of an understanding of cookies at this point.
Session
Cookies are stored on the client side, sessions are stored on the server side, and clients only store sessionids
We’ve seen what a Cookie is, and since browsers already implement stateful cookies, why a Session? Here we can imagine that if some information of an account is stored in cookies, once the information is intercepted, all of our account information will be lost. Therefore, sessions are created. Important information is stored in a Session, and the browser only records the Session ID. Each Session id corresponds to one Session request.
1@RequestMapping("/testSession")
2@ResponseBody
3public String testSession(HttpSession session){
4 session.setAttribute("testSession"."this is my session");
5 return "testSession";
6}
7
8
9@RequestMapping("/testGetSession")
10@ResponseBody
11public String testGetSession(HttpSession session){
12 Object testSession = session.getAttribute("testSession");
13 return String.valueOf(testSession);
14}
Copy the code
So here we’re going to write a new way to test how a Session is generated, and we’re going to say HttpSession Session, Then type http://localhost:8005/testSession in the browser to access can be seen in the server’s head back in Cookie generated a SessionId. The browser then remembers that the SessionId can be brought with it the next time it visits, and it can find information stored on the server based on that Id.
At this time we access path http://localhost:8005/testGetSession, found that got us the above information stored in the Session. So when does the Session expire?
- Client: and
Cookie
Expiration is consistent, if not set, the default is to close the browser, that is, open the browser when the initial request header is notSessionId
. - Server side: Expiration of the server side is true expiration, that is, the server side
Session
How long has the stored data structure been unavailable? The default is 30 minutes.
Now that we know that sessions are managed on the server side, you might see a few questions here, where is the Session created? What data structure is the Session stored in? Let’s take a look at how sessions are managed.
Session management is managed in a container. What is a container? Tomcat, Jetty, and so on are containers. Let’s take the most commonly used Tomcat as an example to see how Tomcat manages sessions. CreateSession in ManageBase is used to create a Session.
1@Override
2public Session createSession(String sessionId) {
3 // Check whether the number of sessions has reached the maximum. The maximum number of sessions can be set by parameter setting
4 if ((maxActiveSessions >= 0) &&
5 (getActiveSessions() >= maxActiveSessions)) {
6 rejectedSessions++;
7 throw new TooManyActiveSessionsException(
8 sm.getString("managerBase.createSession.ise"),
9 maxActiveSessions);
10 }
11
12 // Reuse or create a new Session object, which in Tomcat is StandardSession
13 // It is a concrete implementation class for HttpSession, which is the interface defined in the Servlet specification
14 Session session = createEmptySession();
15
16
17 // Initialize the value of the new Session
18 session.setNew(true);
19 session.setValid(true);
20 session.setCreationTime(System.currentTimeMillis());
21 // Set the Session expiration time to 30 minutes
22 session.setMaxInactiveInterval(getContext().getSessionTimeout() * 60);
23 String id = sessionId;
24 if (id == null) {
25 id = generateSessionId();
26 }
27 session.setId(id);// Session is added to ConcurrentHashMap
28 sessionCounter++;
29
30 // Add the creation time to the LinkedList and remove the first time added
31 // It is mainly convenient to clean up expired sessions
32 SessionTiming timing = new SessionTiming(session.getCreationTime(), 0);
33 synchronized (sessionCreationTiming) {
34 sessionCreationTiming.add(timing);
35 sessionCreationTiming.poll();
36 }
37 return session
38}
Copy the code
Here we see how the Session is created. Once created, the Session is saved to a ConcurrentHashMap. You can look at the StandardSession class.
1protected Map<String, Session> sessions = new ConcurrentHashMap<>();
Copy the code
So this should give you a little bit of an idea of sessions.
Session is stored in the Tomcat container, so if there are multiple back-end machines, the Session cannot be shared between multiple machines. In this case, you can use the distributed Session solution provided by Spring, which is to store the Session in Redis.
Token
Session means that the information to be verified is stored in the server and corresponding to the data with the SessionId. The SessionId is stored by the client, and the SessionId is also carried over when the request is made, so the corresponding state is realized. The Token method is that the server sends the user information encoded by Base64Url to the client. Each time the user requests this information, the server can find out who the user is after decrypting the information. This method is called JWT(Json Web Token).
The advantage of Token compared with Session is that when multiple back-end systems are deployed, the client directly carries data when accessing the Token. Therefore, data sharing is not required.
The advantages of the Token
- Concise: Yes
URL
.POST
The parameter is either inHTTP
The header parameter is sent because the data volume is small and the transmission speed is fast - Self-contained: Because the string contains the information the user needs, multiple queries to the database are avoided
- Because tokens are stored on the client side as Json, JWT is cross-language
- There is no need to save session information on the server, especially for distributed micro services
The structure of the JWT
The actual JWT looks something like this, it’s a long string, and it’s used in the middle. Divided into three parts
JWT is made up of three parts
Header
Is a Json object that describes the metadata of a JWT, usually something like this
1{
2 "alg": "HS256".
3 "typ": "JWT"
4}
Copy the code
In the above code, the ALG attribute represents the algorithm of the signature. The default is HMAC SHA256 (written as HS256). The TYp attribute represents the type of the token, and the JWT token is written as JWT. Finally, convert the above JSON object into a string using the Base64URL algorithm.
JWT as a token may be placed in a URL in some cases (such as api.example.com/?token=xxx). Base64 has three characters +, /, and =, which have special meanings in URLS and are therefore replaced: = is omitted, + is replaced with -, and/is replaced with _. This is the Base64URL algorithm.
Payload
Payload is also a Json object used to store data that needs to be transmitted. JWT defines the following official fields for selection.
- Iss (Issuer) : indicates the issuer
- Exp (expiration Time) : expiration time
- Sub (subject) : indicates the topic
- Aud (audience) : Audience
- NBF (Not Before) : indicates the effective time
- Iat (Issued At) : time of issue
- Jti (JWT ID) : indicates the ID
Of course, we can also define our own private fields in addition to the official fields. Here is an example
1{
2 "name": "xiaoMing".
3 "age": 14
4}
Copy the code
JWT is unencrypted by default, and anyone can read information by Base64 decoding on the web, so don’t put secret information in this section. The Json object is also converted to a string using the Base64URL algorithm
Signature
The Signature part is used to sign the data of the previous two parts to prevent data tampering.
You need to define a secret key, which is known only by the server and cannot be leaked to users. Then, use the Signature algorithm specified in the Header (HMAC SHA256 by default) to calculate the Signature and compose the Header, Payload, and Signature into a string. Split it up and give it back to the user.
HS256 can create a signature for a given sample of data using a single key. When the message is transmitted with the signature, the recipient can use the same key to verify that the signature matches the message.
How do you use tokens in Java
Above we have introduced some concepts about JWT. How can we use it? Start by introducing Jar packages into your project
1compile('the IO. Jsonwebtoken: JJWT: 0.9.0')
Copy the code
And then code it as follows
1// The signature algorithm will sign the token
2SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
3// Sign JWT with the secret key
4byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("SECRET");
5Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
6Map<String.Object> claimsMap = new HashMap<>();
7claimsMap.put("name"."xiaoMing");
8claimsMap.put("age".14);
9JwtBuilder builderWithSercet = Jwts.builder()
10 .setSubject("subject")
11 .setIssuer("issuer")
12 .addClaims(claimsMap)
13 .signWith(signatureAlgorithm, signingKey);
14System.out.printf(builderWithSercet.compact());
Copy the code
The Token output is as follows
1eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdWJqZWN0IiwiaXNzIjoiaXNzdWVyIiwibmFtZSI6InhpYW9NaW5nIiwiYWdlIjoxNH0.3KOWQ-oYvBSzslW5vgB1D-JpCwS-HkWGyWdXCP5l3Ko
Copy the code
At this point in the Internet to find a Base64 decoding site will be able to decode the information
conclusion
I believe you should have a certain understanding of Cookie, Session, Token, next to review the important knowledge points
- Cookies are stored on the client side
- A Session is stored on the server and can be understood as a status list. Has a unique session id
SessionId
. According toSessionId
The storage information is displayed on the server. - Sessions cause a problem of Session sharing with multiple machines on the back end, and the solution can be solved using the framework provided by Spring.
- Token is like a Token, stateless, server information is Base64 encoded into the Token, the server can directly decode the data.
GitHub code address
Suppose you want to read
- Learn these list algorithm questions, interviews are no longer afraid of handwritten list
- Is it so hard for Spring transactions to propagate properties? This one is enough
- Some considerations for backend framework development
- Compress 20M files from 30 seconds to 1 second optimization process
- Why override hashCode() when you override equals()
Refer to the article
- Cookies vs. Tokens: The Definitive Guide
- Thoroughly understand session, cookie, and token
- Perspective HTTP protocol
- Manager component: Resolves the Session management mechanism of Tomcat
- JSON Web Token Tutorial
- SpringBoot integrates with JWT for token authentication
- JSON Web Token – Securely transfers information between Web applications