概述
服务端签名后直传的方式:
服务端签名后直传(Server Signature Direct Upload)是一种安全的文件上传方式,其中文件上传的签名是在服务端生成的,而不是在客户端生成。这样可以防止客户端直接上传文件而绕过服务器的权限控制。
这种方式的优点是可以在服务端进行更细粒度的控制,例如限制上传文件的大小、类型,以及存储路径等。客户端只需要负责文件上传,而上传权限和规则都由服务端掌控。这样可以提高文件上传的安全性和可控性。
安装aliyun的包 ali-oss
json
"ali-oss": "^6.17.1",
"dayjs": "^1.11.7",
"buffer": "^6.0.3",
ali-oss (^6.17.1)
:
ali-oss 是阿里云 OSS(Object Storage Service)的官方 Node.js SDK。
用于在 Node.js 环境中与阿里云 OSS 进行交互,包括上传、下载、删除文件等操作。
允许在应用中直接使用 Node.js 代码访问和管理阿里云 OSS 中的对象。
dayjs (^1.11.7)
:
dayjs 是一个轻量级的 JavaScript 日期库,用于解析、操作和格式化日期。
与 Moment.js 相比,dayjs 更小巧,性能更好,同时提供了类似的功能,使日期处理更加方便。
buffer (^6.0.3)
:
buffer 是 Node.js 内置模块,用于处理二进制数据。
提供了对二进制数据的处理和转换功能,包括创建 Buffer 对象、拼接、切片等。
在文件处理、网络通信等场景中常用于处理二进制数据。
这些包在项目中的使用场景可能如下:
- ali-oss:用于将文件上传到阿里云 OSS 或从 OSS 中下载文件。
- dayjs:用于处理和格式化日期,提供更轻量级的替代方案。
- buffer:在处理二进制数据时可能会使用,例如文件上传、数据流处理等。
对于server端,在modules中创建oss文件夹(oss对应的module),
创建oss.module.ts
此处展示完整代码,实际需要先创建oss.service,以及oss.resolver,再进行引入
python
import { Module } from '@nestjs/common';
import { OSSService } from './oss.service';
import { OSSResolver } from './oss.resolver';
@Module({
imports: [],
providers: [OSSResolver, OSSService],
exports: [],
})
export class OSSModule {}
providers: [OSSResolver, OSSService]
: providers 数组包含了该模块提供的服务提供者。在这里,包括了 OSSResolver 和 OSSService,它们都是用 @Injectable() 装饰器装饰的服务类。
OSSResolver
: 用于处理与 OSS 相关的 GraphQL 请求和操作。
OSSService
: 提供获取阿里云 OSS 签名的服务
编写oss.service
配置oss相关 config
arduino
const config = {
accessKeyId: 'LTAI5t6D9W6ArgXXXX',
accessKeySecret: '8YNGXLtXXTOIRXXXXXnt',
bucket: 'healthflex',
dir: 'images/',
};
这是一个配置对象,其中包含了一些用于连接和访问阿里云 OSS(Object Storage Service)的必要信息。
accessKeyId
:
该属性存储阿里云账户的 Access Key ID。
Access Key ID 用于标识阿里云账户,是访问和操作阿里云资源的身份标识。
accessKeySecret
:
该属性存储阿里云账户的 Access Key Secret。
Access Key Secret 是与 Access Key ID 配套使用的密钥,用于对请求的签名和验证。
bucket
:
bucket 是阿里云 OSS 中的存储桶,相当于一个命名空间,用于存储对象(文件)。
在这里,'healthflex' 是存储桶的名称,表示你要访问的特定存储桶。
dir
:
dir 表示上传文件时的目录,用于在存储桶内组织对象的存储结构。
在这里,'images/' 表示上传的文件将存储在存储桶的 'images/' 目录下。
这个配置对象通常会被用于初始化阿里云 OSS 客户端,在使用 ali-oss 等相关库的 API 时,作为参数传递给初始化的函数。这样,阿里云 OSS 客户端就能够使用这些信息来与指定的存储桶进行通信,执行文件上传、下载等操作。
文件上传服务由于要返回查询结果,所以要定义返回的类型OSSType
定义dto,添加返回对象的类型
less
import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType()
export class OSSType {
@Field({ description: '过期时间' })
expire: string;
@Field({ description: '策略' })
policy: string;
@Field({ description: '签名' })
signature: string;
@Field({ description: 'key' })
accessId: string;
@Field({ description: 'host' })
host: string;
}
以下是oss.service的完整代码
typescript
import { Injectable } from '@nestjs/common';
import * as OSS from 'ali-oss';
import * as dayjs from 'dayjs';
import { OSSType } from './dto/oss.type';
@Injectable()
export class OSSService {
// 获取签名
async getSignature(): Promise<OSSType> {
const config = {
accessKeyId: 'LTAI5t8pPGHBcjAVASD3swxxD',
accessKeySecret: 'kXkYy76asdasdcDQjdAXXXXXXXsaasdeasdfSlyM',
bucket: 'healthflex',
dir: 'images/',
};
const client = new OSS(config);
const date = new Date();
date.setDate(date.getDate() + 1);
const policy = {
expiration: date.toISOString(), // 请求有效期
conditions: [
['content-length-range', 0, 1048576000], // 设置上传文件的大小限制
],
};
// bucket域名
const host = `http://${config.bucket}.${
(await client.getBucketLocation()).location
}.aliyuncs.com`.toString();
//签名
const formData = await client.calculatePostSignature(policy);
//返回参数
const params = {
expire: dayjs().add(1, 'days').unix().toString(),
policy: formData.policy,
signature: formData.Signature,
accessId: formData.OSSAccessKeyId,
host
};
return params;
}
}
@Injectable()
: 这是 NestJS 中的装饰器,用于标记这个类是一个可注入的服务(Service)。通过这个装饰器,NestJS 可以将这个类的实例注入到其他组件(如 Controller)中使用。
import * as OSS from 'ali-oss';: 使用 import * as 语法将整个 'ali-oss' 模块的所有导出内容放在一个名为 OSS 的对象中,以便在后续代码中使用。
async getSignature(): Promise: 这是一个异步方法,用于获取阿里云 OSS 的签名。返回一个 Promise,Promise 的值是一个类型为 OSSType 的对象。
const config = { ... }
;: 定义了用于创建 OSS 客户端的配置对象,包括阿里云的 Access Key、Bucket 名称和文件夹路径。
const client = new OSS(config)
;: 创建了阿里云 OSS 客户端实例。
const date = new Date(); ...: 创建了一个日期对象,然后计算了请求的有效期,并定义了上传文件的大小限制条件。
const formData = await client.calculatePostSignature(policy);
: 使用 OSS 客户端计算了上传策略的签名,该签名将用于安全地将文件上传到 OSS。
const params = { ... };: 创建了一个包含签名等参数的对象,用于返回给调用方。
return params;: 返回包含签名等参数的对象,Promise 的结果。
这个服务类的目的是为前端应用提供获取阿里云 OSS 签名的功能,以便安全地上传文件到 OSS。
创建oss.resolver
typescript
import { Query, Resolver } from '@nestjs/graphql';
import { OSSType } from './dto/oss.type';
import { OSSService } from './oss.service';
@Resolver()
export class OSSResolver {
constructor(private readonly ossService: OSSService) {}
@Query(() => OSSType, { description: '获取oss相关信息' })
async getOSSInfo(): Promise<OSSType> {
return await this.ossService.getSignature();
}
}
@Resolver()
: 这是 NestJS 中用于定义 GraphQL 解析器的装饰器。通过 @Resolver() 装饰器,可以将类标记为 GraphQL 解析器,并定义解析器中的查询和变更操作。
constructor(private readonly ossService: OSSService) {}
: 解析器的构造函数接收一个参数 ossService,它是 OSSService 类的实例。这是通过 NestJS 的依赖注入系统注入的,用于在解析器中调用 OSSService 的功能。
@Query(() => OSSType, { description: '获取oss相关信息' })
: 这是一个 GraphQL 查询操作的装饰器,表示下面的 getOSSInfo 方法是用于处理查询操作的。它的参数说明了该查询的返回类型是 OSSType,并提供了一个描述字符串。
async getOSSInfo(): Promise<OSSType>
: 这是一个异步方法,用于处理 GraphQL 查询操作,返回一个 Promise,Promise 的值是一个类型为 OSSType 的对象。在该方法中,调用了 ossService.getSignature(),该方法是 OSSService 中的功能,用于获取阿里云 OSS 的签名信息。
总体来说,OSSResolver 类负责定义与 OSS 相关的 GraphQL 查询操作,它通过依赖注入系统使用 OSSService 提供的功能。在这个例子中,getOSSInfo 方法返回了获取的 OSS 签名信息,用于在前端应用中安全地上传文件到阿里云 OSS。
最终要记得在app.module.ts中引入oss.module
最终在graphql调试面板执行查询
markdown
query getOSSInfo{
getOSSInfo{
expire
policy
signature
accessId
graphql
}
}
总结
最终总结一下,对于服务端来说:
OSSModule(oss.module)
:
作用: OSSModule 是一个 NestJS 模块,用于组织和配置与 OSS 相关的功能。
构成:
导入模块:在示例中没有导入其他模块,但在实际应用中,可能需要导入其他相关的 NestJS 模块。
提供者:注册了 OSSResolver 和 OSSService,使它们在整个应用程序中可用。
OSSResolver(oss.resolver)
:
作用: OSSResolver 是一个 NestJS GraphQL 解析器,用于处理与 OSS 相关的 GraphQL 查询。
构成:
类装饰器:使用 @Resolver() 装饰器标记为一个 GraphQL 解析器类。
构造函数:接收 OSSService 的实例,通过依赖注入系统注入,用于在解析器中调用 OSS 相关服务。
查询操作:使用 @Query() 装饰器定义了查询操作 getOSSInfo,并指定了返回类型为 OSSType。
OSSService(oss.service)
:
作用: OSSService 是一个 NestJS 服务,提供了获取阿里云 OSS 签名的功能。
构成:
类装饰器:使用 @Injectable() 装饰器标记为一个可注入的服务类。
方法:包含了异步方法 getSignature,用于获取阿里云 OSS 的签名信息。
这三个部分一起构成了一个完整的后端服务的查询模块,用于处理前端应用发起的获取 OSS 签名的 GraphQL 查询。通过 NestJS 的依赖注入系统,OSSResolver 可以调用 OSSService 提供的功能,从而实现了模块内部的功能组合。前端应用可以通过调用 getOSSInfo 查询获取 OSS 相关信息,并使用这些信息在前端应用中安全地上传文件到阿里云 OSS。