tangshi300/node_modules/cos-wx-sdk-v5/server/sts.js

164 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 临时密钥服务例子
var bodyParser = require('body-parser');
var STS = require('qcloud-cos-sts');
var express = require('express');
var crypto = require('crypto');
// 配置参数
var config = {
secretId: process.env.SecretId,
secretKey: process.env.SecretKey,
proxy: process.env.Proxy,
durationSeconds: 1800,
bucket: process.env.Bucket,
region: process.env.Region,
// 允许操作(上传)的对象前缀,可以根据自己网站的用户登录态判断允许上传的目录,例子: user1/* 或者 * 或者a.jpg
// 请注意当使用 * 时可能存在安全风险详情请参阅https://cloud.tencent.com/document/product/436/40265
allowPrefix: '_ALLOW_DIR_/*',
// 简单上传和分片,需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/14048
allowActions: [
// 所有 action 请看文档 https://cloud.tencent.com/document/product/436/31923
// 简单上传
'name/cos:PutObject',
'name/cos:PostObject',
// 分片上传
'name/cos:InitiateMultipartUpload',
'name/cos:ListMultipartUploads',
'name/cos:ListParts',
'name/cos:UploadPart',
'name/cos:CompleteMultipartUpload'
],
};
// 创建临时密钥服务
var app = express();
app.use(bodyParser.json());
// 格式一:临时密钥接口
app.all('/sts', function (req, res, next) {
// TODO 这里根据自己业务需要做好放行判断
if (config.allowPrefix === '_ALLOW_DIR_/*') {
res.send({error: '请修改 allowPrefix 配置项,指定允许上传的路径前缀'});
return;
}
// 获取临时密钥
var LongBucketName = config.bucket;
var ShortBucketName = LongBucketName.substr(0, LongBucketName.lastIndexOf('-'));
var AppId = LongBucketName.substr(LongBucketName.lastIndexOf('-') + 1);
var policy = {
'version': '2.0',
'statement': [{
'action': config.allowActions,
'effect': 'allow',
'resource': [
'qcs::cos:' + config.region + ':uid/' + AppId + ':prefix//' + AppId + '/' + ShortBucketName + '/' + config.allowPrefix,
],
}],
};
var startTime = Math.round(Date.now() / 1000);
STS.getCredential({
secretId: config.secretId,
secretKey: config.secretKey,
proxy: config.proxy,
region: config.region,
durationSeconds: config.durationSeconds,
policy: policy,
}, function (err, tempKeys) {
if (tempKeys) tempKeys.startTime = startTime;
res.send(err || tempKeys);
});
});
// // 格式二:临时密钥接口,支持细粒度权限控制
// // 判断是否允许获取密钥
// var allowScope = function (scope) {
// var allow = (scope || []).every(function (item) {
// return config.allowActions.includes(item.action) &&
// item.bucket === config.bucket &&
// item.region === config.region &&
// (item.prefix || '').startsWith(config.allowPrefix);
// });
// return allow;
// };
// app.all('/sts-scope', function (req, res, next) {
// var scope = req.body;
//
// // TODO 这里根据自己业务需要做好放行判断
// if (config.allowPrefix === '_ALLOW_DIR_/*') {
// res.send({error: '请修改 allowPrefix 配置项,指定允许上传的路径前缀'});
// return;
// }
// // TODO 这里可以判断 scope 细粒度控制权限
// if (!scope || !scope.length || !allowScope(scope)) return res.send({error: 'deny'});
//
// // 获取临时密钥
// var policy = STS.getPolicy(scope);
// var startTime = Math.round(Date.now() / 1000);
// STS.getCredential({
// secretId: config.secretId,
// secretKey: config.secretKey,
// proxy: config.proxy,
// durationSeconds: config.durationSeconds,
// policy: policy,
// }, function (err, tempKeys) {
// if (tempKeys) tempKeys.startTime = startTime;
// res.send(err || tempKeys);
// });
// });
//
// 用于 PostObject 签名保护
app.all('/post-policy', function (req, res, next) {
var query = req.query;
var now = Math.round(Date.now() / 1000);
var exp = now + 900;
var qKeyTime = now + ';' + exp;
var qSignAlgorithm = 'sha1';
var policy = JSON.stringify({
'expiration': new Date(exp * 1000).toISOString(),
'conditions': [
// {'acl': query.ACL},
// ['starts-with', '$Content-Type', 'image/'],
// ['starts-with', '$success_action_redirect', redirectUrl],
// ['eq', '$x-cos-server-side-encryption', 'AES256'],
{'q-sign-algorithm': qSignAlgorithm},
{'q-ak': config.secretId},
{'q-sign-time': qKeyTime},
{'bucket': config.bucket},
{'key': query.key},
]
});
// 签名算法说明文档https://www.qcloud.com/document/product/436/7778
// 步骤一:生成 SignKey
var signKey = crypto.createHmac('sha1', config.secretKey).update(qKeyTime).digest('hex');
// 步骤二:生成 StringToSign
var stringToSign = crypto.createHash('sha1').update(policy).digest('hex');
// 步骤三:生成 Signature
var qSignature = crypto.createHmac('sha1', signKey).update(stringToSign).digest('hex');
console.log(policy);
res.send({
policyObj: JSON.parse(policy),
policy: Buffer.from(policy).toString('base64'),
qSignAlgorithm: qSignAlgorithm,
qAk: config.secretId,
qKeyTime: qKeyTime,
qSignature: qSignature,
// securityToken: securityToken, // 如果使用临时密钥,要返回在这个资源 sessionToken 的值
});
});
app.all('*', function (req, res, next) {
res.send({code: -1, message: '404 Not Found'});
});
// 启动签名服务
app.listen(3000);
console.log('app is listening at http://127.0.0.1:3000');