# [Node] Authentication

# Cookie vs. Session

* **Cookie**: When the browser receives the Set-Cookie header from the server as a response, it stores the data and sends it in all subsequent requests. Since data can be shared across multiple sites, **cookies can be vulnerable to security risks**. Cookies exist in string format, such as `userId=user-1321;userName=siwon`, and are separated by a semicolon (`;`).
    
* **Session**: A technology based on cookies. However, unlike cookies, which allow clients to access data freely, **sessions store data only on the server, making them more secure**. However, **when many users use the system, the amount of data to be stored on the server increases, which can lead to problems where the server computer cannot handle the load**.
    

## How to Set & Get Cookie

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681782549678/48e1e643-a222-4e20-8212-7c34773d2750.png align="center")

When the server receives a client's HTTP request, it can send a header called Set-Cookie along with the response. Then, **the cookie is received along with the response generated by the server, contained within the Cookie HTTP header**.

```javascript
const cookieParser = require("cookie-parser");
app.use(cookieParser());

app.get("/set-cookie", (req, res) => {
	let expires = new Date();
	expires.setMinutes(expires.getMinutes() + 60); 

	res.cookie("name", "siwon", {
		expires: expires,
	});
	return res.status(200).end();
});
```

```javascript
app.get("/get-cookie", (req, res) => {
	const cookie = req.cookies; // cookie-parser middleware was used (without this, use req.header.cookie)
	console.log(cookie); // { name: 'siwon' }
	return res.status(200).json({ cookie });
});
```

## How to Set & Get Session

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681782868514/2fe7e908-0fd9-4a73-a9e2-9de8d6120052.png align="center")

\-&gt; Session object looks like this

![](https://res.cloudinary.com/practicaldev/image/fetch/s--jzM6Wq6e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2AP5OxJMihg0S0jyqk.png align="left")

```javascript
let session = {};
app.get("/set-session", function (req, res, next) {
	const name = "siwon"; // user data that will be stored in the server
	const uniqueInt = Date.now(); // get cookie using this key
	session[uniqueInt] = { name }; // key: uniqueInt, value: name

	res.cookie("sessionKey", uniqueInt); // store sessionKey in cookie
	return res.status(200).end();
});
```

```javascript
app.get("/get-session", function (req, res, next) {
	const { sessionKey } = req.cookies; // get sessionKey from the cookie
	const name = session[sessionKey]; // get user name by using sessionKey
	return res.status(200).json({ name });
});
```

# JWT: JSON Web Token

![](https://res.cloudinary.com/practicaldev/image/fetch/s--xAjXADfz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/0%2A16xpkdbQ1tuFphvs.png align="left")

* It enables secure exchange and use of data in JSON format.
    
* It is a widely recognized internet standard specification.
    
* Various encryption algorithms can be used.
    
* It contains three types of data in the format of `header.payload.signature`.
    

### Type of Data: `header.payload.signature`

1. **header** - store what algorithm/tokenization is used in the signature to encode data
    
2. **payload** - the actual data (claim)
    
3. **signature** - check if the token has been tampered with or not
    

![](https://teamsparta.notion.site/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F4ade6645-2ee4-4233-98d9-c9f468eed8d4%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2022-09-09_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%258C%25E1%2585%25A5%25E1%2586%25AB_5.55.01.png?id=a51f2681-e02f-45b3-945a-dcba5732a761&table=block&spaceId=83c75a39-3aba-4ba4-a792-7aefe4b07895&width=860&userId=&cache=v2 align="left")

* Even if you do not know the secret key, JWT can be **decrypted (decoded)**. This means that anyone can decrypt and view it, as long as it has not been tampered with.
    
* Therefore, **sensitive information (personal information, passwords, etc.)** should not be included in JWT.
    

### What is JWT Bearer?

* Typically, tokens are sent in the Authorization field of the request header as follows:  
    `Authorization: <type> <credentials>`
    
* type
    
    * Basic: encoded in base 64
        
    * **Bearer: JWT or OAuth token**
        
    * Digest: RFC 7616
        
    * HOBA: RFC 7486 - HTTP Origin-Bound Authentication
        

### Cookie & Session VS. JWT

Unlike the cookie/session approach, which is a way of exchanging and managing data, JWT is simply a **format for representing data**.

Although data created with JWT is not automatically stored in the browser like a cookie, it is almost impossible to tamper with and can be used to manage the server in a **stateless** manner, as it does not store data on the server. This is why JWT is one of the most popular technologies used today.

### Stateless

In a stateless server, the server does not store any session information about the client between requests. **Each request is treated as an independent transaction that does not depend on any previous requests**. This means that the server does not need to maintain any client-specific state, which can **improve scalability and reduce the complexity of the server**. However, it also means that the client needs to include all necessary information in each request, which can increase the size of the requests and potentially reduce performance.

## How to use JWT

```javascript
const payloadData = {
    myPayloadData: 1234
}

const token = jwt.sign(payloadData, "mysecretkey"); // encoding
const decodedToken = jwt.decode(token) // decoding

// when creating jwt, verify if the secret key is correct
const decodedValueByVerify = jwt.verify(token, "mysecretkey")
console.log(decodedValueByVerify); // payloadData

// verify with wrong key
const decodedValueByVerifywithError = jwt.verify(token, "wrongKey")
console.log(decodedValueByVerifywithError); // error
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1681779160334/f384412d-e652-4887-9d6d-00a3a3eda9a7.png align="center")

* [http://jwt.io/](http://jwt.io/): to decode
    

## Why JWT?

* Without JWT
    
    ```javascript
    const express = require('express');
    const app = express();
    
    app.post('/login', function (req, res, next) {
      const user = { // critical user info
        userId: 203, // Primary key
        email: "siwonkim1108@gmail.com", 
        name: "Siwon Kim", 
      }
    
      res.cookie('hashnode', user);  // Assign the user object to a cookie named "hashnode"
      return res.status(200).end();
    });
    
    app.listen(5002, () => {
      console.log(5002, "Port Server");
    });
    ```
    
    * The user's information is assigned to a cookie named "hashnode" directly.
        
    * The client can modify the attributes or expiration time of the cookie at any time.
        
    * It is not possible to verify whether the cookie has been tampered with.
        
* With JWT
    
    ```javascript
    const express = require('express');
    const JWT = require("jsonwebtoken");
    const app = express();
    
    app.post('/login', async (req, res) => {
      const user = {
        userId: 203,
        email: "siwonkim1108@gmail.com",
        name: "Siwon Kim",
      }
    
      // Encode user information with JWT
      const userJWT = await JWT.sign(user, // Assign user data to a payload
        "secretOrPrivateKey", // Assign JWT's secret key as secretOrPrivateKey
        { expiresIn: "1h" } // Set JWT expiration time as 1 hour
      );
    
      // Assign userJWT variable to a cookie named 'hashnode' with Bearer token type
      res.cookie('hashnode', `Bearer ${userJWT}`);
      return res.status(200).end();
    });
    
    app.listen(5002, () => {
      console.log(5002, "Port Server");
    });
    ```
    
    * The JWT, which contains the user's information as payload, is assigned to a cookie named "hashnode".
        
    * **A secret key, which allows verifying whether the JWT has been tampered with, was used to create the JWT**.
        
    * In addition to the expiration time of the cookie, the expiration time of the JWT was also set.
        

# Wrap-Up: Cookie, Session & JWT

* **<mark>Cookie</mark>**: Automatically generated by the browser as a **medium for carrying session ID/tokens**.
    
* **<mark>Session</mark>**:
    
    * When a user logs in, their information is stored in a session database using the cookie.
        
    * The session ID is stored within the cookie and sent back to the browser for storage.
        
    * When the user makes subsequent requests, the cookie containing the session ID is sent to the server.
        
    * The server uses the session ID to look up the user's information in the session database.
        
    * Summary:
        
        1. Browser --- Cookie with user information ---&gt; Server
            
        2. Server --- **Stores user info in session DB** and returns session ID within Cookie ---&gt; Browser
            
        3. Browser --- Cookie with session ID ---&gt; Server
            
        4. Server --- **Looks up user based on session ID in session DB** ---&gt; Identifies user
            
* **<mark>JWT</mark>**:
    
    * **Does not require a session database (but still needs to store a secret key), so the server does not need to do as much work.**
        
    * When a user logs in and their information matches, the server creates a JWT token by signing their user ID and sends it in a cookie.
        
    * When the user makes subsequent requests, they send the cookie containing the JWT token, and the server validates the token to determine if it has expired, been tampered with, and if it was created by the server.
        
    * The server can then identify the user without needing to look up their information in a session database.
        
    * Summary:
        
        1. Browser --- User information in cookie ---&gt; Server
            
        2. Server --- **Signs user ID to create JWT token** and sends it in cookie ---&gt; Browser
            
        3. Browser --- Cookie with JWT token ---&gt; Server
            
        4. Server --- **Validates JWT token** ---&gt; Identifies user
            

# Resources

* [Cookie vs. Session vs. Token](https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC)
    
* [Session based vs. Token based authentication](https://dev.to/thecodearcher/what-really-is-the-difference-between-session-and-token-based-authentication-2o39)
    
* [Access Token & Refresh Token](https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-Access-Token-Refresh-Token-%EC%9B%90%EB%A6%AC-feat-JWT?category=889117)
    
* Sign up using user Info from another website: [OAuth 2.0](https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-OAuth-20-%EA%B0%9C%EB%85%90-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC?category=889117)
    
* How to make passwords more secure: [Crypto Module](https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-crypto-%EB%AA%A8%EB%93%88-%EC%95%94%ED%98%B8%ED%99%94#%EC%95%94%ED%98%B8%ED%99%94%EC%97%90_%EC%82%AC%EC%9A%A9%EB%90%98%EB%8A%94_%EB%A9%94%EC%86%8C%EB%93%9C)
