The difference between session and cookie

“What’s the difference between a cookie and a session?”

This is a classic and open interview question. Most interviewees can only answer: cookie is stored in browser, session is stored in browser. But interviewees who give such answers without further explanation are more likely to memorize the interview questions. The best answer I have seen is this one on Zhihu, which can be answered by a person who really understands session and cookie:

Interview questions like these are actually “open” questions, and you can go anywhere. However, if I were the interviewer, I would expect one thing from the interviewer: don’t confuse session with session implementation.

Originally, session is an abstract concept. Developers abstract one-to-one interaction between user agent and server into “session” in order to realize operations such as interruption and continuation, and then derive “session state”, which is the concept of session. A cookie is an actual thing, a header field defined in the HTTP protocol. Think of it as a back-end stateless implementation of session.

In order to circumvent the limitations of cookies, the “session” is often referred to today. It is usually implemented with the help of cookies and back-end storage, a more advanced session state implementation.

So cookies and sessions, you can either think of them as being at the same level or you can think of them as being at different levels. In terms of implementation, session is usually realized by cookie because of the existence of session ID, but this is not necessary. It can only be said that it is a kind of implementation scheme with good universality.

What’s the difference between cookies and sessions? – the answer to the night – zhihu www.zhihu.com/question/19…

Session in English, the original meaning of the meaning of the session, meeting and session, specifically refers to the computer field is the session. HTTP is a stateless protocol, but there is a lot of “session state” ** in the browser and server session.

The most common of these “session states” is login state, which is used to identify the user’s identity, and the server provides corresponding content for different users. In addition to login state, user behavior data and user form filling can also be session state. Cookies and sessions are implementations of maintaining “session state.”

Cookie is a technology provided by the browser, which allows the server to record “session state” on the browser. However, the capacity of saving “session state” through cookies is not large, and the data type is relatively simple, because the browser limits the size of cookies to about 4KB and can only be strings of data type.

Session is also a form of “session state”, but it keeps the “session state” on the server. The SESSION_ID (a unique ID) is saved by cookies, and the data of the session state mapped by the SESSION_ID is retrieved on the server. This is commonly called session. Cookie is a universal implementation of session, but it is not the only one.

Sessions are used in express.js

Download and use middleware

Implementing sessions in express.js requires the use of middleware express-session. Let’s download it using NPM:

$ npm install express-session
Copy the code

This middleware is then used in Express

const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const port = 3099;
const session = require("express-session");

app.use(bodyParser());
app.use(
  session({
    key: 'SESSION_ID'.secret: "your_secret_key".resave: false.saveUninitialized: false.cookie: { maxAge: 1000 * 60 * 60 * 8.signed: true}})); app.listen(port,() = > {
  console.log(`node listening at http://localhost:${port}`);
});

Copy the code

The middleware supports the following parameters

 cookie: {
  // Cookie Options
  // Default {path: '/', httpOnly: true, secure: false, maxAge: null}
   /** maxAge: specifies the number of milliseconds (date) for a given expiration date. Expires: Specifies a UTC expiration date. Cookie path (default /) (string) * domain: set domain name, default current domain (string) * sameSite: Cookie for the same site (default false) (can be set to ['lax', 'None ',' None '] or true) * Secure: Whether to send a cookie in HTTPS (false in HTTP). True in HTTPS) true is the default option. However, it requires HTTPS enabled sites. Cookies are not set if your site is accessed over HTTP. If Secure: True is used, you need to set Trust Proxy in express. * httpOnly: Whether to send cookies only as HTTP (s), which is not available to client JS (default is true, i.e. clients cannot view cookies as document.cookie) * signed: Whether to include a signature for cookies (default true) * Overwrite: Whether to overwrite previous cookies with the same name (default true) */
  },
    
  // By default, the uID-safe library is used to automatically generate ids
  genid: req= > genuuid(),  
    
  // Set the key in the cookie to store the sessionId. The default is connect.sid
  name: 'value'.// Trust the reverse proxy when setting secure cookies (by setting "X-Forwarded-Proto" to the request header). Default undefined (Boolean)
  proxy: undefined.// Whether to force the session to be saved, even if it is not modified. The default is true
  resave: true.// Forces a session identifier cookie to be set on each response. Expiration resets to the original maxAge, resets the expiration countdown. The default value is false.
  rolling: false.// Forces the "uninitialized" session to be saved to storage. When a session is new but not modified, it is uninitialized. Choosing False is useful for implementing login sessions, reducing server storage usage, or complying with laws that require permission before setting cookies. The choice of False also helps to resolve the competitive condition of a client making multiple parallel requests without a session. The default value is true.
  saveUninitialized: true.// The key used to generate the session signature
  secret: 'your_secret_key'.// Session storage instance, new MemoryStore instance by default.
  store: new MemoryStore(),
  
  // Sets whether to save the session. The default is keep. If you don't save, you can set 'destory'
  unset: 'keep'
Copy the code

Set up the session

The following code is a user login route, req.session.authInfo = authInfo we set authInfo to hold some user permissions.

⚠️ It is important to note that setting up sessions in Express-session is implemented on REQ, not the common RES.

// User login
app.post("/login".async function (req, res) {
  const { name, pwd } = req.body;
  const isValid = await validateUserLogin(name, pwd); // Verify user login
  const authInfo = await getUserAuthInfo(name); // Obtain user permission information
  if (isValid) {
    req.session.authInfo = authInfo
    res.send({
      success: true.info: "Login successful"}); }else {
    res.send({
      success: false.info: "Login failed"}); }});Copy the code

If you’re using a POST request in your browser/loginIf the interface login succeeds, you can see a key in the cookieSESSION_IDCookie record.

To view the session

Req. session is also used to check the session. We return req.session directly on the/interface.

app.get("/".async function (req, res) {
  res.send(req.session);
});
Copy the code

If you see the access/interface through your browser, you will receive the following return value, where authInfo is the user related permission information we reserved previously.

{
	"cookie": {
		"originalMaxAge": 28800000."expires": "The 2021-09-23 T22:43:05. 458 z"."httpOnly": true."path": "/"
	},
	"authInfo": {
		"name": "abc"."path": ["/html"."/css"."/js"]}}Copy the code

Delete the session

To remove the cookie, we simply delete the data in req.session. You can use delete req.session.authInfo or select reflect.deleteProperty () in ES6.

app.get("/logout".async function (req, res) {
  Reflect.deleteProperty(req.session, 'authInfo')
  res.send({
    success: true.info: "Logout successful"})});Copy the code

Persistent session

So far, our sessions have been stored in memory, which can be done during debugging, but never in actual production. This means that once we restart the application, all users’ “session state” disappears. The common practice is to store session data in an in-memory database such as Redis.

The express-Session official documentation lists a number of storage schemes for persistent sessions. For example, connect-mongo and connect-redis.

connect-mongo

Here we use MongoDB for session persistence. First we install related dependencies:

$ npm install mongodb connect-mongo
Copy the code

Then use it in express-session middleware:

const MongoStore = require('connect-mongo');

app.use(
  session({
    name: 'SESSION_ID'.secret: "your_secret_key".resave: false.saveUninitialized: false.cookie: { maxAge: 1000 * 60 * 60 * 8.signed: true },
    store: MongoStore.create({ mongoUrl: 'mongodb://localhost:27017/session_test'})}));Copy the code

Then try to restart the Express service and our session will persist.