认证Bearer:从普遍性到高标准的安全认证

发布时间:2023-05-20

Bearer认证方式的概念和原理

Bearer认证方式是一种常见的授权验证方案,其核心在于使用访问令牌来验证用户身份。Bearer是OAuth2.0协议中一个基于令牌的认证机制,即使用令牌而不是密码来获取受保护的资源。 与其他类型的令牌相比,Bearer Token最直接的特征是令牌可以使用不同的数字证书加密,例如基于HTTPS的加密,因此Bearer Token能够提供更加全面的安全保护。 Bearer Token是OAuth2.0中最主要的一种令牌类型,流程如下:

+------------+                                +---------------+
| Resource   |                                | Authorization |
|  Server    | 1.  Request to access user      |     Server    |
|            |     account                    |               |
|            +------------------------------->|               |
|            |                                |               |
|            |                                |               |
|            |                                |               |
|            |                                |               |
|            |     4.  Issue access token     |               |
|            |<-------------------------------+               |
|            |                                |               |
|            |    5.  Access Token             |               |
|            |                                |               |
|            |                                |               |
|            |2.Deliver response with         |               |
|            |  authorization server URL      |               |
|            |  token                         |<--------------+
|            |                                |
+------------+                                +---------------+

Bearer Token通过使用访问令牌来验证用户的身份。这种验证方式由OAuth2.0所提供。 Bearer Token主要由以下两部分构成:

  • 令牌:Bearer Token它是一组由服务器发放的字符串代码,同时其通常具有特定的过期时间。
  • 授权:Bearer Token通过有效的网路验证,来确定令牌所有者使用该令牌可以访问哪些资源。

构建一个基于Bearer Token的验证机制

开发一个基于Bearer Token验证的机制需要以下步骤:

第一步、开发Server部分代码

const express = require('express');
const jwt = require('jsonwebtoken');
const { authenticate } = require('./middlewares/authenticate');
const app = express();
const port = process.ENV.PORT || 3000;
const user = [
  {
    id: 1,
    username: 'user1',
    password: 'password1'
  },
  {
    id: 2,
    username: 'user2',
    password: 'password2'
  }
];
app.use(express.json());
app.get('/', (req, res) => {
  res.send('Hello World!');
});
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const userFound = user.find(user => {
    return user.username === username && user.password === password;
  });
  if (userFound) {
    const token = jwt.sign(userFound, 'secretkey');
    res.json({ token });
  } else {
    res.status(401).json({ message: 'Invalid credentials' });
  }
});
app.get('/secret', authenticate, (req, res) => {
  res.json(req.user);
});
app.listen(port, () => {
  console.log(`Server started on port ${port}`);
});

第二步、开发authenticate中间件代码

const jwt = require('jsonwebtoken');
const authenticate = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (authHeader) {
    const token = authHeader.split(' ')[1];
    jwt.verify(token, 'secretkey', (err, user) => {
      if (err) {
        return res.status(401).json({ message: 'Invalid or expired token' });
      }
      req.user = user;
      next();
    });
  } else {
    res.status(401).json({ message: 'Token not found' });
  }
};
module.exports = { authenticate };

第三步、测试API

const request = require('supertest');
const app = require('../index');
const token = jwt.sign({ id: 1 }, 'secretkey');
describe('GET /secret', () => {
  it('Should return 401 if no token', async () => {
    const res = await request(app).get('/secret');
    expect(res.statusCode).toEqual(401);
    expect(res.body.message).toEqual('Token not found');
  });
  it('Should return 401 if invalid token', async () => {
    const res = await request(app)
      .get('/secret')
      .set('Authorization', 'Bearer ' + 'invalidtoken');
    expect(res.statusCode).toEqual(401);
    expect(res.body.message).toEqual('Invalid or expired token');
  });
  it('Should return 200 if valid token', async () => {
    const res = await request(app)
      .get('/secret')
      .set('Authorization', `Bearer ${token}`);
    expect(res.statusCode).toEqual(200);
  });
});

Bearer Token在实际场景中的应用

Bearer Token的应用非常广泛,在许多常见的API验证方案中都有采用,例如:

  1. Google APIs
    Google APIs使用OAuth2.0并基于JWT或OAuth2.0的Bearer Token进行访问令牌验证。
  2. Stripe APIs
    Stripe APIs也采用OAuth2.0并基于JWT或OAuth2.0的Bearer Token进行访问令牌验证,其借助于Authorization服务器以及Token服务器实现访问权限管理。
  3. GitHub APIs
    GitHub APIs采用OAuth2.0进行验证,并基于OAuth2.0的Bearer Token进行访问令牌验证。 通过以上案例可以看出,Bearer Token的应用非常广泛,并且在实际中大量被使用。Bearer Token可以帮助开发者构建简单、快速和安全的验证方案,同时其也是一种基于OAuth2.0的应用的好选择。