laitimes

Session Authentication vs Token Authentication: Which is Better?

author:Not bald programmer
Session Authentication vs Token Authentication: Which is Better?

In this article, we'll take a look at the session and token-based authentication methods used in back-end applications.

Session-based authentication

In simple terms, session-based authentication uses a special code (Session ID) stored on your device to remember who you are when you visit a website, stay logged in, and remember your information until you leave or log out.

Don't worry, let's take a step at a time.

1. User Login:

The user logs in by sending an email address and password to the server via a special request.

2. Check the details:

The server checks to see if the details provided match the information stored for the user.

3. Create a session:

If everything is correct, the server creates a "Session" that holds user information such as User ID, permissions, and time limits. This information is kept securely in the server's storage, and the name can be such as express-session.

4. Get the session ID:

The server sends this "session ID" back to the user's device, usually as a cookie in the response.

5. Use Session ID:

Whenever a user wants to get something from the server, their device automatically includes this session ID in their request.

6. Server Check:

The server uses this session ID to look up information stored in the session store about the session user.

Here's how express-session works:

  • When a user logs in, the server creates a session for that user and sets a cookie in the response containing the session ID.
  • The browser automatically includes this session ID cookie in subsequent requests to the server.
  • When the server receives a request, the express-session middleware uses the session ID in the cookie to retrieve the relevant session data.
  • Data stored in req.session, such as userId, can be used to process requests.

7. Grant Access:

If everything matches, the server knows that the user is genuine and responds to what they requested.

Session Authentication vs Token Authentication: Which is Better?

Code examples

Here's an example of an Node.js application that uses Express.js to implement session authentication.

const express = require('express');

const session = require('express-session');

const app = express();

// 中间件设置
app.use(session({
  secret: 'your_secret_key',
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true, // Set the cookie as HTTP-only, Optional
    maxAge: 60*30 // In secs, Optional
  }
}));


//登录

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);

  if (user) {
    req.session.userId = user.id; // Store user ID in session
    res.send('Login successful');
  } else {
    res.status(401).send('Invalid credentials');
  }
});
//受保护页面
app.get('/home', (req, res) => {
  if (req.session.userId) {
    // User is authenticated
    res.send(`欢迎您光临,${req.session.userId}!`);
  } else {
    // User is not authenticated
    res.status(401).send('Unauthorized');
  }
});
//登出
app.get('/logout', (req, res) => {
  req.session.destroy(err => {
    if (err) {
      res.status(500).send('退出登录出现错误');
    } else {
      res.redirect('/'); // Redirect to the home page after logout
    }
  });
});           

Token-based authentication

JWT authentication uses a digitally signed token (Token) that contains user information, which allows secure and authenticated access to a website or application without the need for repeated logins.

Let's take a look at the step-by-step workflow for token-based authentication.

1. User Login Request:

The user logs in by sending an email and password to the server through a specific request.

2. Credential Verification:

The server verifies the provided credentials against the stored user data.

3. Token Generation:

After successful validation, the server creates a token (typically a JWT - JSON web token). The token holds user information (claims), such as user_id, permissions.

4. Token Signing and Hashing:

The token is signed with a key and processed using a hashing algorithm such as SHA256 to create a hash.

5. Send Tokens:

The server sends this token to the client, which typically stores it in the browser.

6. Token Storage Options:

Clients can store tokens in different ways, such as HttpOnly cookies, session storage, or local storage. It is recommended to store in HttpOnly cookies, as it prevents JavaScript access, thus enhancing security against XSS attacks.

7. Token Expiration and Security:

Tokens usually have an expiration time for added security.

8. Include the token in the request:

For each request made to the server, the client sends a token in the authorization header.

It's a good idea to prefix the token with the "Bearer" prefix.

axios.get(URL, {
    headers: {
        'Authorization': 'Bearer ' + token,
    },
})           

9. Server-Side Verification:

After receiving the request, the server retrieves the token.

10. Token Validation and User Authentication:

Using the key, the server validates the token and extracts the claims from it. If the user information in the claim exists in the server's user table, the server authenticates the user and grants access to the requested resource.

Session Authentication vs Token Authentication: Which is Better?

Code examples

//登录
app.post('/login', (req, res) => {

const { username, password } = req.body;
  const user = users.find(u => u.username === username && u.password === password);

  jwt.sign({ user }, secretKey, { expiresIn: '1h' }, (err, token) => {
    if (err) {
      res.status(500).send('Error generating token');
    } else {
      res.json({ token });
    }
  });
});           

Handle protected pages

We use the veriyToken() function as middleware to handle each route that needs to be validated. The request goes through, veriyToken() and only when next() calls the function, it is passed to that route and implements the code.

app.get('/dashboard', verifyToken, (req, res) => {
  res.send('Welcome to the Home page');
});

// Verify token middleware
function verifyToken(req, res, next) {
  const token = req.headers['authorization'];

  if (typeof token !== 'undefined') {
    jwt.verify(token.split(' ')[1], secretKey, (err, decoded) => {
      if (err) {
        res.status(403).send('Invalid token');
      } else {
        req.user = decoded.user;
        next();
      }
    });
  } else {
    res.status(401).send('Unauthorized');
  }
}           

Differences between the two methods

  • Storage location: Sessions are stored on the server, while tokens (JWTs) are stored on the client.
  • Stateful vs. stateless: Sessions are stateful, while tokens are stateless, allowing for better scalability in distributed systems.
  • Expiration Processing: Session expiration is managed by the server, while token expiration is handled by the token itself.
  • Security measures: JWTs typically include digital signature and encryption support, enhance security compared to typical session mechanisms that use cookies, and can be vulnerable to CSRF attacks if not properly protected.
  • Flexibility of use: Tokens (JWTs) provide more flexibility in carrying additional information beyond authentication, which is useful for authorization and custom data transfers.

Which method should I use?

It depends on the requirements and nature of the application. Most applications use a hybrid approach, token-based authentication against APIs, and session-based authentication for web-based interactions.