express-session & cookie
Published: 2022-11-16 04:11:07

1. HTTP is stateless, after a response is sent, the client and the server will forgot about each other. Cookies and URL parameters can store data but it's readable to client side. Session can store data on the server side. When a session is created, an ID will be assigned to the user, and the further requests are made with the ID, so the server can recognize the user.
2. A session middleware example. connect-session-sequelize package is used to store session data.
```
app.use(
    session({
        secret: 'dahuang',
        cookie: { maxAge: 172800000, secure: false, sameSite: 'strict' },
        resave: false,
        saveUninitialized: false,
        store: new SequelizeStore({
            db: sequelize,
        })
    })
);
```

3  [The difference between session and cookie](https://www.geeksforgeeks.org/difference-between-session-and-cookies/): Cookies are client-side files on a local computer that hold user information. Sessions are server-side files that contain user data. Cookies end on the lifetime set by the user. When the user quits the browser or logs out of the programmed, the session is over.

4 To make it easy for client side to attach the session id onto every request, session id are saved in client side in cookies. Cookies are small pieces of data in key-value pairs. A session cookie is set with the first HTTP response from the server and persists until the browser is closed or cookie expires. Cookies are in HTTP header.

5 The flow of how session is implemented with cookie:
 
    - A user goes to a site(a request is sent), the server creates a session and a session id
    - The server sends the session id back to browser in HTTP header, and the browser stores the session id in cookie
    - The session cookie automatically attaches to all the following request to the server.
    - The server receives the request sent with session id, it responses with the data associated with the ID. 

6 passport.js is an authentication package. Here's example of passport local strategy with sequelize. In the server.js file, we need to initialize passport after the session middleware.
```
app.use(passport.initialize());
app.use(passport.session());

```
```
passport.use(
    new LocalStrategy(
        {
            usernameField: 'email',
            passwordField: 'password',
        },
        async (email, password, done) => {
            try {
                const user = await User.findOne({ where: { email: email } });
                if (!user) {
                    return done(null, false, {
                        message: 'email not registered',
                    });
                }
                const matchPassword = await user.checkPassword(password);
                return matchPassword
                    ? done(null, user)
                    : done(null, false, { message: 'Incorrect password' });
            } catch (error) {
                done(error);
            }
        }
    )
);

passport.serializeUser(function(user, done) {
    done(null, user.id);
});

passport.deserializeUser(function(id, done) {
    User.findByPk(id).then(function(user) { done(null, user); });
});
```
* SerializeUser: to persist user data into session. Here we saved the user id, eg: req.session.passport.user = 1.
DeserializeUser to get the user data from session, attach the user data to req as req.user. For more [detail](https://stackoverflow.com/questions/27637609/understanding-passport-serialize-deserializ) about serialize and deserialize user.
* for passport middleware, it takes three params, username(or email), password, and a callback function done(), if there's error, return `done(error)`, if no user is found, return `done(null, false)`, null means no error. If the password doesn't match, return `done(null, false)`. If the username and password both match the data from db, return `done(null, user)`.