概述
需要一对AK/SK
, 权限是只能读取demo-bucket
空间中的demo/permission.txt
, 无空间中其他文件的读取权限;
通过菜单 访问管理>策略管理 中只能提供对整个空间的访问权限, 不满足要求;
通过菜单 空间管理>选择指定空间>空间设置>空间授权 是为其他用户设置访问权限且是整个空间, 不满足要求;
开发文档中(https://developer.qiniu.com/af/12495/kodo-iam-actions
)有说明可以对具体资源的配置, 但是需要通过接口(https://developer.qiniu.com/kodo/6317/BucketPolicy
)进行配置;
本文通过nodejs
进行配置(node:v18.17.0, npm:9.6.7
);
注意: 只对同空间中授权和未授权文件的Get权限进行了测试, 其余场景未测试
步骤
获取endpoint
在空间管理的列表中点击需要设置的空间名称, 打开空间概览, 向下滑动找到基础配置, 复制endpoint
创建账号
在管理账号下创建IAM用户,菜单: 右上角头像图标 > 访问管理 > 用户管理 > 创建用户;
新创建的用户需要访问用户管理>概览>用户登录链接下的链接通过账号密码登录;
获取新建用户的AK/SK
在用户管理选项中找到刚才新建的用户名, 点击用户名, 在新开的页面的底部找到AK/SK
获取根用户ID和IAM用户ID
按下F12, 打开浏览器的调试界面, 在顶部切换到Network, 在搜索框中粘贴新建用户名, 找到网络记录中users结尾的请求;
点击请求, 在Response
选项中, 找到alias
为刚才新建用户名的记录, 复制其中root_uid
和iuid
获取管理账号的AK/SK
访问秘钥管理界面, 获取AK/SK
编写接口
参考: https://developer.qiniu.com/kodo/12558/aws-sdk-javascript-examples
- 创建一个文件夹用于存放代码, 如
qiniu-s3
- 进入文件夹执行
npm init -y
- 安装依赖
npm i typescript@5.2.2 ts-node@10.9.1 @types/node@20.8.4 --save-dev
npx tsc --init
新增策略
新建bucket-policy.ts
通过参考文档中的上传示例可以推测region
是endpoint
中s3
和qiniucs
中间的那部分
import { S3Client, PutBucketPolicyCommand, GetBucketPolicyCommand,DeleteBucketPolicyCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({
region: "输入region",
endpoint: "输入endpoint",
credentials: {
accessKeyId: "输入管理员的AK",
secretAccessKey: "输入管理员的SK",
},
});
let policy =
{
"Version":"s3.v1",
"Id": "samplepolicy", // 可自定义
"Statement" : [
{
"Effect":"Allow",
"Principal" : {
"AWS":["iam::输入root_uid:输入iuid"]
},
"Action":["s3:GetObject"],
"Resource":"arn:aws:s3:::demo-bucket/demo/permission.txt"
}
]
}
新增策略
s3.send(
new PutBucketPolicyCommand({
Bucket:'demo-bucket',
Policy: JSON.stringify(policy)
})
).then((data) => console.log(data)).catch((err) => console.error(err));
查询策略
s3.send(
new GetBucketPolicyCommand({
Bucket:'demo-bucket',
})
).then((data) => console.log(data)).catch((err) => console.error(err));
删除策略
s3.send(
new DeleteBucketPolicyCommand({
Bucket:'demo-bucket'
})
).then((data) => console.log(data)).catch((err) => console.error(err));
保留其中一个s3.send
, 注释掉其他2个s3.send
, 然后执行npx ts-node .\bucket-policy.ts
, 查看控制台输出
新建用户访问文件
新建get-object.ts
, 复制参考文档中 对象下载>服务器端直接下载的示例
将accessKeyId
和secretAccessKey
配置为新建用户的AK/SK
import * as fs from "fs";
import {
S3Client,
GetObjectCommand,
GetObjectCommandOutput,
} from "@aws-sdk/client-s3";
import { Writable } from "stream";
import Readable from "stream";
async function getObject(
s3: S3Client,
bucket: string,
key: string,
writable: Writable
): Promise<GetObjectCommandOutput> {
const getObjectCommandOutput = await s3.send(
new GetObjectCommand({
Bucket: bucket,
Key: key,
})
);
if (getObjectCommandOutput.Body) {
(getObjectCommandOutput.Body as Readable).pipe(writable);
}
return getObjectCommandOutput;
}
const s3 = new S3Client({
region: "输入region",
endpoint: "输入endpoint",
credentials: {
accessKeyId: "输入新建用户的AK",
secretAccessKey: "输入新建用户的SK"
},
});
let filename = "permission.txt";
// let filename = "permission2.txt";
// 注意demo前无/
getObject(s3, "demo-bucket", "demo/"+filename, fs.createWriteStream("./"+filename))
.then((data) => console.log(data)).catch((err) => console.error(err));
执行npx ts-node .\get-object.ts
查看文件是否下载成功(控制台提示和文件内容)
切换filename
到未授权的文件, 再次执行命令, 查看是否下载成功(控制台提示和文件内容)
其他
- npm设置了淘宝的镜像
https://registry.npm.taobao.org
, 但是更新失败, 提示证书过期, SSL错误- 在浏览器访问该地址会跳转到一个新的地址
https://registry.npmmirror.com/
- 执行
npm config set registry https://registry.npmmirror.com/
重新设置镜像地址
- 在浏览器访问该地址会跳转到一个新的地址