Skip to content
⚠️ This article was written in 2020. Some content may be outdated.

JWT Frontend Authentication and Security Best Practices

JWT-based frontend authentication and its security practices are being adopted more and more widely in frontend development. Starting from real projects, this article takes a deep look at the core principles and best practices.

Basic Usage ​

Here's how we can improve on it:

javascript
function setCSP(req, res, next) {
  const nonce = crypto.randomBytes(16).toString('base64')
  res.setHeader('Content-Security-Policy', [
    "default-src 'self'",
    `script-src 'self' 'nonce-${nonce}'`,
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data: https:",
    "connect-src 'self' https://api.example.com",
    "frame-ancestors 'none'"
  ].join('; '))
  next()
}

This approach has been running stably in production for over half a year, so it's proven in practice.

Advanced Usage ​

Let's start with the basic implementation:

javascript
function setCSP(req, res, next) {
  const nonce = crypto.randomBytes(16).toString('base64')
  res.setHeader('Content-Security-Policy', [
    "default-src 'self'",
    `script-src 'self' 'nonce-${nonce}'`,
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data: https:",
    "connect-src 'self' https://api.example.com",
    "frame-ancestors 'none'"
  ].join('; '))
  next()
}

This snippet shows the basic usage. In real projects you'll still need to account for error handling and edge cases.

Practical Cases ​

Building on this, we can optimize further:

javascript
function setCSP(req, res, next) {
  const nonce = crypto.randomBytes(16).toString('base64')
  res.setHeader('Content-Security-Policy', [
    "default-src 'self'",
    `script-src 'self' 'nonce-${nonce}'`,
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data: https:",
    "connect-src 'self' https://api.example.com",
    "frame-ancestors 'none'"
  ].join('; '))
  next()
}

This pattern is very practical in large projects and can significantly cut maintenance cost.

Performance Optimization ​

In real projects, the usage gets a bit more involved:

javascript
function setCSP(req, res, next) {
  const nonce = crypto.randomBytes(16).toString('base64')
  res.setHeader('Content-Security-Policy', [
    "default-src 'self'",
    `script-src 'self' 'nonce-${nonce}'`,
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data: https:",
    "connect-src 'self' https://api.example.com",
    "frame-ancestors 'none'"
  ].join('; '))
  next()
}

This approach improves both the testability and extensibility of the code.

Common Traps ​

Here is a complete example:

javascript
function setCSP(req, res, next) {
  const nonce = crypto.randomBytes(16).toString('base64')
  res.setHeader('Content-Security-Policy', [
    "default-src 'self'",
    `script-src 'self' 'nonce-${nonce}'`,
    "style-src 'self' 'unsafe-inline'",
    "img-src 'self' data: https:",
    "connect-src 'self' https://api.example.com",
    "frame-ancestors 'none'"
  ].join('; '))
  next()
}

Pay attention to edge-case handling — it's critical in production.

Summary ​

  • In team collaboration, conventions and documentation matter more than the technology itself.
  • Keep an eye on community developments; technical solutions need continuous iteration.
  • Don't adopt new tech for its own sake.
  • The code examples are for reference only and should be adapted to your actual use case.
  • JWT-based frontend authentication and security practices are no silver bullet; choose them based on your project's scale and tech stack.

MIT Licensed