Authentication and Authorization


Authentication and Authorization Interview with follow-up questions

1. Can you explain the difference between authentication and authorization in Node.js?

Authentication answers "who are you?" — verifying identity (credentials, a token, a social login). Authorization answers "what are you allowed to do?" — deciding whether the authenticated principal may access a resource or action. Authentication always comes first; authorization happens on each protected operation.

app.use(authenticate);                 // authN: sets req.user or 401s
app.delete('/admin/users/:id',
  requireRole('admin'),                // authZ: 403 if not permitted
  deleteUser);

In Node this typically looks like: authN via sessions (cookie + server store) or JWT/OAuth/OIDC tokens, attaching the verified user to the request; authZ via role- or attribute-based checks (RBAC/ABAC) in middleware/guards before the handler runs.

The gotchas interviewers probe: a failed authN returns 401 Unauthorized, a failed authZ returns 403 Forbidden; and broken access control (forgetting an authZ check, or trusting a client-supplied role/ID — IDOR) is consistently a top OWASP risk. So authenticate once, but authorize on every sensitive request, server-side.

↑ Back to top

Follow-up 1

What are some common methods for implementing authentication in Node.js?

Some common methods for implementing authentication in Node.js include:

  1. Session-based authentication: This method involves storing the user's session data on the server and sending a session ID to the client, which is used to identify the user in subsequent requests.

  2. Token-based authentication: This method involves generating a token, such as a JSON Web Token (JWT), which is sent to the client upon successful authentication. The client then includes this token in subsequent requests to authenticate the user.

  3. OAuth: OAuth is an open standard for authorization that allows users to grant third-party applications access to their resources without sharing their credentials. It involves redirecting the user to the OAuth provider's login page and obtaining an access token to authenticate the user.

These are just a few examples, and the choice of authentication method depends on the specific requirements of the application.

Follow-up 2

What libraries can you use for authorization in Node.js?

There are several libraries available for authorization in Node.js. Some popular ones include:

  1. express-jwt: This library provides middleware for validating JSON Web Tokens (JWT) and implementing role-based authorization in Express.js.

  2. passport: Passport is a flexible authentication middleware for Node.js that can also be used for authorization. It supports various authentication strategies, such as local authentication, OAuth, and OpenID.

  3. casl: CASL is an isomorphic authorization library for Node.js that allows you to define permissions and perform authorization checks based on those permissions.

These are just a few examples, and the choice of library depends on the specific requirements and preferences of the application.

Follow-up 3

How would you handle role-based authorization in Node.js?

Role-based authorization in Node.js can be implemented using various approaches. Here is one possible approach:

  1. Define roles and permissions: Start by defining the roles and their corresponding permissions in your application. For example, you might have roles like 'admin', 'user', and 'guest', with different permissions for each role.

  2. Assign roles to users: When a user is authenticated, assign them a role based on their credentials or any other criteria. This can be done during the registration process or by updating the user's role in the database.

  3. Implement authorization middleware: Create a middleware function that checks the user's role and the required permissions for the requested resource or action. If the user's role has the necessary permissions, allow the request to proceed; otherwise, return an error or redirect the user to an appropriate page.

  4. Apply the middleware to routes: Apply the authorization middleware to the routes that require role-based authorization. This can be done using Express.js middleware.

By following this approach, you can ensure that only users with the appropriate roles and permissions can access certain resources or perform specific actions in your Node.js application.

2. How would you implement JWT authentication in Node.js?

Use the jsonwebtoken library: on login, verify credentials and sign a token with claims; on later requests, verify the token in middleware and attach the user.

import jwt from 'jsonwebtoken';

// issue a short-lived access token after verifying the password
const accessToken = jwt.sign(
  { sub: user.id, role: user.role },
  process.env.JWT_SECRET,            // secret from env, never hard-coded
  { expiresIn: '15m' }
);

// verify on protected routes
function auth(req, res, next) {
  try {
    req.user = jwt.verify(req.cookies.token, process.env.JWT_SECRET);
    next();
  } catch { res.status(401).json({ error: 'Invalid token' }); }
}

The best-practices that separate a strong answer (the original snippet's hard-coded 'secretKey' is a red flag):

  • Keep the secret in env/secret storage; for multi-service setups prefer asymmetric RS256/ES256 (sign with a private key, verify with the public key).
  • Use short-lived access tokens (minutes) plus a refresh token to get new ones; you can't easily revoke a stateless JWT before it expires, so keep TTLs short or maintain a denylist.
  • Store tokens in httpOnly, Secure, SameSite cookies, not localStorage (XSS-exposed).
  • Never put secrets in the payload — it's only base64-encoded, not encrypted — and always validate exp/issuer/audience.
↑ Back to top

Follow-up 1

What are the advantages and disadvantages of using JWT for authentication?

Advantages of using JWT for authentication:

  • Stateless: JWTs are self-contained and contain all the necessary information, eliminating the need for server-side session storage.
  • Scalability: Since JWTs are stateless, they can be easily scaled across multiple servers.
  • Decentralized: JWTs can be used across different services and domains.

Disadvantages of using JWT for authentication:

  • Token size: JWTs can be larger in size compared to other authentication mechanisms like session cookies.
  • Token revocation: JWTs cannot be easily revoked once issued, as they are valid until they expire.
  • Token storage: JWTs need to be stored securely to prevent unauthorized access.

Follow-up 2

How would you handle token expiration and refresh tokens?

To handle token expiration and refresh tokens with JWT authentication, you can set an expiration time for the JWT token and use refresh tokens to obtain a new JWT token when the current token expires. Here's an example:

  1. When a user logs in, generate a JWT token with an expiration time (e.g., 1 hour).
  2. Send the JWT token to the client.
  3. When the JWT token expires, the client can send a refresh token to the server.
  4. Verify the refresh token and issue a new JWT token with a new expiration time.
  5. Send the new JWT token to the client.

You can store the refresh tokens securely on the server and associate them with the user's session or database record.

Follow-up 3

What measures would you take to secure JWTs?

To secure JWTs, you can take the following measures:

  1. Use strong secret keys: Choose a long and random secret key to sign the JWT tokens.
  2. Set short expiration times: Keep the expiration time of JWT tokens short to minimize the window of opportunity for attackers.
  3. Use HTTPS: Always use HTTPS to encrypt the communication between the client and server, preventing man-in-the-middle attacks.
  4. Implement token revocation: Maintain a blacklist of revoked tokens and check each token against the blacklist before accepting it.
  5. Store tokens securely: Store JWT tokens securely on the client-side, using mechanisms like HttpOnly cookies or local storage with appropriate security measures.
  6. Implement token rotation: Rotate the secret key periodically to mitigate the impact of a compromised key.
  7. Validate token signatures: Verify the signature of JWT tokens to ensure their integrity.

3. What is OAuth and how can it be used for authentication in Node.js?

OAuth 2.0 is an authorization framework (technically OAuth 2.1 is the consolidated current spec): it lets a user grant a third-party app delegated, scoped access to their resources on another service without sharing their password. The app receives an access token representing that grant. The familiar "Sign in with Google/GitHub" buttons are built on it.

In Node you usually don't hand-roll the flow — you use a library: Passport with a provider strategy (passport-google-oauth20, etc.) or a spec-compliant client like openid-client.

passport.use(new GoogleStrategy({ clientID, clientSecret, callbackURL },
  (accessToken, refreshToken, profile, done) => done(null, profile)));
app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
app.get('/auth/google/callback', passport.authenticate('google'), (req, res) => res.redirect('/'));

The crucial clarification interviewers want: OAuth 2.0 is for authorization, not authentication. Using a raw access token to "log in" is an anti-pattern — for identity you use OpenID Connect (OIDC), the authentication layer on top of OAuth 2.0 that returns an ID token identifying the user. Also use the Authorization Code flow with PKCE (the modern standard; the implicit flow is deprecated), and validate state to prevent CSRF.

↑ Back to top

Follow-up 1

Can you explain the OAuth flow?

The OAuth flow consists of the following steps:

  1. The client application initiates the OAuth flow by redirecting the user to the OAuth provider's authorization endpoint.
  2. The user is prompted to log in to the OAuth provider and grant permission to the client application.
  3. The OAuth provider generates an authorization code and redirects the user back to the client application's redirect URL.
  4. The client application exchanges the authorization code for an access token by making a request to the OAuth provider's token endpoint.
  5. The OAuth provider verifies the authorization code and returns an access token to the client application.
  6. The client application can then use the access token to make authorized requests on behalf of the user.

This flow may vary slightly depending on the OAuth version and the specific implementation.

Follow-up 2

What are some popular services that use OAuth?

OAuth is widely used by many popular services for authentication. Some examples of services that use OAuth include:

  • Google: OAuth is used for authentication and authorization in services like Google Sign-In and Google APIs.
  • Facebook: OAuth is used for authentication and authorization in the Facebook Login feature.
  • Twitter: OAuth is used for authentication and authorization in the Twitter API.

These are just a few examples, and many other services also support OAuth for authentication.

Follow-up 3

What are the security considerations when using OAuth?

When using OAuth for authentication, there are several security considerations to keep in mind:

  1. Secure storage of access tokens: Access tokens should be securely stored to prevent unauthorized access. They should not be exposed in client-side code or transmitted over insecure channels.
  2. Token expiration and revocation: Access tokens should have a limited lifespan and should be revoked when no longer needed. This helps mitigate the risk of token leakage or misuse.
  3. User consent and authorization: Users should be informed about the permissions requested by the client application and should have the ability to grant or deny access.
  4. Secure communication: All communication between the client application, OAuth provider, and resource server should be encrypted using secure protocols like HTTPS.

By following these security best practices, the risk of unauthorized access or data breaches can be minimized when using OAuth for authentication.

4. How would you handle password storage in Node.js?

Never store passwords in plaintext or reversible/encrypted form — store a slow, salted, one-way hash. On signup, hash the password and persist only the hash; on login, hash the attempt and compare with a constant-time verify.

  • Algorithm: Argon2id (OWASP's recommended default) or bcrypt at cost 12+. Avoid MD5/SHA-* — they're far too fast and built for speed, not password storage.
  • Salt: unique per user, automatically generated and embedded by argon2/bcrypt — so you don't manage it separately (it defeats rainbow tables).
import argon2 from 'argon2';
const hash = await argon2.hash(password);        // store this
const valid = await argon2.verify(hash, attempt); // login check

Rounding it out: never log raw passwords; transmit only over HTTPS/TLS; enforce strong password policies and ideally check against known-breached lists; support MFA; and keep any extra secret ("pepper") in env/secret storage, separate from the database. The headline: hash with Argon2id/bcrypt, per-user salt, constant-time compare — never plaintext or fast hashes.

↑ Back to top

Follow-up 1

What are the risks of storing passwords in plain text?

Storing passwords in plain text is highly insecure and should be avoided. The main risks include:

  1. Passwords can be easily read by anyone who has access to the database, including malicious actors who gain unauthorized access.
  2. Users often reuse passwords across multiple accounts, so if one account is compromised, all other accounts with the same password are also at risk.
  3. Compliance with data protection regulations, such as GDPR, may be violated, leading to legal consequences and reputational damage.

Follow-up 2

What is hashing and why is it important for password storage?

Hashing is the process of converting data (in this case, passwords) into a fixed-length string of characters using a mathematical algorithm. The resulting hash is unique to the input data, meaning even a small change in the input will produce a completely different hash. Hashing is important for password storage because:

  1. It adds an extra layer of security by ensuring that the original password cannot be easily derived from the stored hash.
  2. It protects user passwords in case of a data breach, as the attacker would need to spend significant time and computational resources to reverse-engineer the original passwords from the hashes.

Follow-up 3

What libraries can you use for password hashing in Node.js?

There are several popular libraries for password hashing in Node.js, including:

  1. bcrypt: A widely-used library that implements the bcrypt algorithm, which is a slow hashing algorithm designed to be computationally expensive. This makes it resistant to brute-force and dictionary attacks.

Example usage:

const bcrypt = require('bcrypt');

const password = 'myPassword';
const saltRounds = 10;

bcrypt.hash(password, saltRounds, function(err, hash) {
  // Store the hash in the database
});
  1. argon2: A newer library that implements the Argon2 algorithm, which is currently considered the most secure password hashing algorithm. It is designed to be memory-hard and resistant to GPU-based attacks.

Example usage:

const argon2 = require('argon2');

const password = 'myPassword';

argon2.hash(password).then(hash => {
  // Store the hash in the database
}).catch(err => {
  // Handle error
});

Both bcrypt and argon2 are widely used and have good community support. It is recommended to use one of these libraries for secure password hashing in Node.js.

5. What is OpenID Connect and how does it relate to OAuth 2.0?

OpenID Connect (OIDC) is a thin authentication (identity) layer on top of OAuth 2.0. OAuth 2.0 by itself only handles authorization (delegated, scoped access via an access token) and deliberately says nothing about who the user is. OIDC fills that gap in a standardized way.

What OIDC adds on top of OAuth's flows:

  • ID token — a signed JWT containing identity claims (sub, email, name, iss, aud, exp) that the client validates to know who logged in.
  • /userinfo endpoint — fetch additional profile claims.
  • Standardized discovery (.well-known/openid-configuration) and JWKS for verifying token signatures, plus the openid scope.

The key point interviewers want: OAuth 2.0 = authorization, OIDC = authentication built on it. Using a bare OAuth access token to "log a user in" is the classic mistake — you should use OIDC's ID token for identity. In Node, libraries like openid-client (or Passport OIDC strategies) implement the flow correctly, typically via the Authorization Code flow with PKCE. "Sign in with Google/Microsoft/Okta" are OIDC providers.

↑ Back to top

Follow-up 1

What are the benefits of using OpenID Connect?

There are several benefits of using OpenID Connect:

  1. Single Sign-On (SSO): OpenID Connect enables users to authenticate once and then access multiple applications without the need to re-enter their credentials.

  2. User Identity Verification: OpenID Connect allows clients to verify the identity of end-users, ensuring that only authorized users can access protected resources.

  3. Standardized Protocol: OpenID Connect provides a standardized protocol for authentication and identity verification, making it easier to implement and integrate with different systems.

  4. Enhanced Security: OpenID Connect incorporates security features such as encryption and token validation, ensuring the confidentiality and integrity of user identity information.

  5. Privacy-Preserving: OpenID Connect allows users to control the release of their personal information by providing consent mechanisms and supporting the concept of claims.

Follow-up 2

How does OpenID Connect handle user information?

OpenID Connect handles user information by using ID tokens and UserInfo endpoint.

When a user authenticates with an OpenID Connect provider, the provider issues an ID token containing information about the user, such as their unique identifier and other claims. The ID token is a JSON Web Token (JWT) that is digitally signed by the provider to ensure its authenticity.

To obtain additional user information, clients can make a request to the UserInfo endpoint using the access token obtained during the authentication process. The UserInfo endpoint returns a JSON object containing the requested user information, such as the user's name, email address, and profile picture.

By using these mechanisms, OpenID Connect allows clients to securely obtain and verify user information without directly accessing the user's credentials.

Follow-up 3

Can you explain the concept of an ID token in OpenID Connect?

In OpenID Connect, an ID token is a JSON Web Token (JWT) that contains information about the authenticated user. It is issued by the OpenID Connect provider (authorization server) after a successful authentication.

The ID token typically includes claims such as the user's unique identifier (sub), name, email address, and other requested information. These claims are digitally signed by the provider to ensure their integrity and authenticity.

Clients can use the ID token to verify the identity of the user and obtain basic user information without making additional requests to the provider. The ID token can also be used to establish a session for the user and enable Single Sign-On (SSO) across multiple applications.

It's important to note that the ID token is meant for client-side use and should not be used for authorization purposes. For authorization, clients should rely on the access token obtained during the authentication process.

Live mock interview

Mock interview: Authentication and Authorization

Intermediate ~5 min Your own free AI key

Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.