Part 124: Enhancing Security in Authentication: Setting Expiry and Attributes for JWTs and Cookies

[App] Authentication Overview

[App] Authentication Overview

In the realm of web security, managing authentication tokens and cookies effectively is crucial. Not only do we want our application to function smoothly, but we also need to ensure it's secure against potential threats. Today, we'll enhance our authentication system by setting expiration times and adding security attributes to our cookies and JSON Web Tokens (JWTs).

Why Set Expiry and Attributes?

By default, session cookies are temporary and will disappear once the user closes their browser. However, JWTs may remain valid indefinitely if not explicitly set to expire. This poses a security risk: a stolen token could allow an attacker to impersonate a user without time constraints. Setting expiration times ensures that both cookies and tokens are valid only for a specified duration. Additionally, configuring cookie attributes enhances security by controlling how cookies are accessed and shared.

Setting Expiry for JWTs and Cookies

We'll begin by defining a duration for our authentication tokens. This duration determines how long a user stays logged in before needing to authenticate again.

Step 1: Define the JWT Duration

Let's start by setting a constant for the JWT duration. We'll choose a period of two weeks, calculated in milliseconds:

// File path: lib/auth.js

const JWT_DURATION = 14 * 24 * 60 * 60 * 1000; // 2 weeks

This value represents 14 days, converted to milliseconds, which is the unit of time used by JavaScript's Date object.

Step 2: Calculate Expiration Time

Next, we'll calculate the expiration time based on the current date and our defined duration.

// File path: lib/auth.js

export async function setSessionCookie(user) {
  const expirationTime = new Date(Date.now() + JWT_DURATION);
  // Additional code follows...
}

Step 3: Set Expiry on JWTs and Cookies

We'll pass the calculated expiration time when signing the JWT and when setting the cookie. This ensures both have the same expiry.

// File path: lib/auth.js

const sessionToken = await new SignJWT(user)
  .setProtectedHeader({ alg: 'HS256' })
  .setExpirationTime(expirationTime)
  .sign(JWT_SECRET);

cookies().set(JWT_COOKIE, sessionToken, {
  expires: expirationTime,
  httpOnly: true,
  sameSite: 'lax',
});

In addition to setting expiry, there are several attributes we can configure to make our cookies more secure:

  • HttpOnly: This attribute prevents client-side JavaScript from accessing the cookie. By setting httpOnly: true, we mitigate the risk of session hijacking through cross-site scripting (XSS) attacks.

  • SameSite: This attribute controls how cookies are sent with cross-site requests, helping to prevent cross-site request forgery (CSRF) attacks. Setting sameSite: 'lax' is a good balance between security and usability, ensuring cookies are only sent with same-site requests or top-level navigation.

Testing and Verifying

To verify these changes:

  1. Delete Existing Cookies: Clear your current cookies to remove any without the new settings.

  2. Sign In Again: Log in to your application to receive a new cookie and JWT with the updated expiration and security settings.

  3. Inspect the Token and Cookie: Use a JWT debugger to check the exp property in the token's payload, and inspect the cookie attributes in your browser's developer tools.

Conclusion

By setting expiration times and security attributes, we enhance the security of our authentication system. This approach ensures tokens are valid only for a limited period, reducing the risk of unauthorized access. Moreover, configuring cookies with attributes like HttpOnly and SameSite adds an additional layer of protection against common web vulnerabilities.

For more information on configuring cookies securely, check out the MDN guide on cookies. This comprehensive resource covers various cookie attributes and how they can be used to bolster security in web applications.

Last updated