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

OAuth 2.0 PKCE 前端认证流程

日常开发中,OAuth 2.0 PKCE 前端认证流程用得越来越频繁。本文系统讲解它的用法、原理和优化策略。

快速上手 ​

在此基础上还能继续优化:

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()
}

这种写法在大型项目里很实用,能明显省下维护成本。

内部原理 ​

实际项目里用起来会更复杂些:

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()
}

这样一来,代码的可测试性和可扩展性都更好了。

业务实战 ​

下面是一个完整示例:

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()
}

生产环境里边界情况务必处理好,这点很关键。

性能对比 ​

关键还是理解背后的核心逻辑:

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()
}

性能优化得看具体场景,不是所有地方都要过度优化。

问题排查 ​

可以试着从下面几个方面改进:

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()
}

这套方案已经在线上稳定运行半年多,是经过实战验证的。

小结 ​

  • 团队协作中约定和文档比技术本身更重要
  • 关注社区动态,技术方案需要持续迭代
  • 不要为了用新技术而用新技术
  • 代码示例仅供参考,需根据业务场景调整

MIT Licensed