面试题答案
一键面试相互TLS认证(mTLS)
- 生成证书:
- 使用OpenSSL等工具生成CA(证书颁发机构)证书、服务端证书和客户端证书。例如,生成CA证书:
openssl req -x509 -newkey rsa:4096 -days 365 -nodes -out ca.crt -keyout ca.key -subj "/CN=MyCA"
- 生成服务端证书和私钥:
openssl req -newkey rsa:4096 -days 365 -nodes -out server.csr -keyout server.key -subj "/CN=server.example.com" openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
- 生成客户端证书和私钥类似:
openssl req -newkey rsa:4096 -days 365 -nodes -out client.csr -keyout client.key -subj "/CN=client.example.com" openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt
- 在Express应用中配置:
- 安装
https
模块(Node.js内置)。 - 在Express应用中使用以下代码配置mTLS:
const express = require('express'); const https = require('https'); const fs = require('fs'); const app = express(); const options = { key: fs.readFileSync('server.key'), cert: fs.readFileSync('server.crt'), ca: fs.readFileSync('ca.crt'), requestCert: true, rejectUnauthorized: true }; app.get('/', (req, res) => { res.send('Hello, mTLS - protected service!'); }); https.createServer(options, app).listen(443, () => { console.log('Server running on port 443 with mTLS'); });
- 客户端在发起请求时也需要配置相应的证书:
const https = require('https'); const fs = require('fs'); const options = { key: fs.readFileSync('client.key'), cert: fs.readFileSync('client.crt'), ca: fs.readFileSync('ca.crt') }; https.get({ hostname: 'localhost', port: 443, path: '/', method: 'GET', rejectUnauthorized: true, ...options }, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { console.log(data); }); }).on('error', (e) => { console.error(e); });
- 安装
JWT令牌用于服务间身份验证
- 安装依赖:
- 在Express项目中安装
jsonwebtoken
:
npm install jsonwebtoken
- 在Express项目中安装
- 生成JWT:
- 在服务端,当服务间需要进行身份验证时,生成JWT。例如,在用户登录成功后生成JWT:
const jwt = require('jsonwebtoken'); const secret = 'your - secret - key'; const user = { username: 'testUser', role: 'admin' }; const token = jwt.sign(user, secret, { expiresIn: '1h' });
- 验证JWT:
- 在接收请求的服务端,验证JWT。创建一个中间件来验证JWT:
const jwt = require('jsonwebtoken'); const secret = 'your - secret - key'; const verifyToken = (req, res, next) => { const token = req.headers['authorization']; if (!token) { return res.status(401).send('Access denied. No token provided.'); } try { const decoded = jwt.verify(token.replace('Bearer ', ''), secret); req.user = decoded; next(); } catch (error) { res.status(400).send('Invalid token.'); } }; app.get('/protected', verifyToken, (req, res) => { res.send('This is a protected route.'); });
基于角色的访问控制(RBAC)
- 定义角色和权限:
- 在项目中定义不同的角色及其对应的权限。例如:
const roles = { admin: ['create', 'read', 'update', 'delete'], user: ['read'] };
- 结合JWT实现RBAC:
- 在验证JWT的中间件基础上,添加RBAC逻辑。例如:
const jwt = require('jsonwebtoken'); const secret = 'your - secret - key'; const roles = { admin: ['create', 'read', 'update', 'delete'], user: ['read'] }; const verifyToken = (req, res, next) => { const token = req.headers['authorization']; if (!token) { return res.status(401).send('Access denied. No token provided.'); } try { const decoded = jwt.verify(token.replace('Bearer ', ''), secret); req.user = decoded; const requiredPermission = 'create';// 假设这个请求需要创建权限 if (!roles[decoded.role].includes(requiredPermission)) { return res.status(403).send('Forbidden. Insufficient permissions.'); } next(); } catch (error) { res.status(400).send('Invalid token.'); } }; app.get('/create - resource', verifyToken, (req, res) => { res.send('Resource created successfully.'); });