1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 微信小程序:阿里云OSS直传实践-PHP实现服务端签名

微信小程序:阿里云OSS直传实践-PHP实现服务端签名

时间:2022-12-21 14:43:44

相关推荐

微信小程序:阿里云OSS直传实践-PHP实现服务端签名

目录

1、阿里云OSS上传方式1.1、Web端Browser.js SDK直传(不推荐)1.2、Web端上传服务端再上传至OSS1.3、服务端签名后Web端直传(推荐) 2、PHP服务端生成签名3、微信小程序客户端

文档

微信小程序直传实践服务端签名直传并设置上传 PHP附录:Post Policy

1、阿里云OSS上传方式

1.1、Web端Browser.js SDK直传(不推荐)

该方法会将AccessKey ID和AccessKey Secret直接保存在浏览器端,存在极高的风险

1.2、Web端上传服务端再上传至OSS

这种方式上传速度慢

1.3、服务端签名后Web端直传(推荐)

该方式安全性和上传速度都不错,本文采用此方式上传

2、PHP服务端生成签名

本例服务端签名生成代码通过官网给出的示例修改而来,基于ThinkPHP框架

服务端签名直传并设置上传 PHP

使用了第三方库ramsey/uuid生成文件名

安装

composer require ramsey/uuid

官网给的示例有callback参数,如果是前端使用签名直接传OSS是不需要这个参数的

结合官网给的Node.js示例,改造PHP代码

微信小程序直传实践 - 服务端签名

AliOssService.php

<?phpnamespace app\service;use Ramsey\Uuid\Uuid;/*** Class AliOssService* @package app\service** 微信小程序直传实践* @see /document_detail/92883.html*/class AliOssService{// 配置oss参数private const AccessKeyId = '<AccessKeyId>';private const AccessKeySecret = '<AccessKeySecret>';private const Host = 'https://<region>.oss-cn-';// 签名有效期 单位: 秒private const Expire = 3 * 60;// 允许上传的文件最大和最小范围 单位:字节private const ContentLengthMin = 0;private const ContentLengthMax = 20 * 1024 * 1024;/*** 获取服务端签名方式上传参数* @param $params array* ext string 扩展名 eg: jpg* dirname string 上传目录 eg: image* @return array* @throws \Exception*/public static function getUploadParams($params){// 接收参数$ext= $params['ext'];$dirname = $params['dirname'];// 文件路径和文件名$dir = self::getDirname($dirname);$key = $dir . self::getFilename($ext);// 过期时间$expiration = self::getExpireTime(self::Expire);// 参数设置// 附录:Post Policy// /document_detail/31988.htm#section-d5z-1ww-wdb$policyParams = ['expiration' => $expiration,'conditions' => [// 指定前缀['starts-with', '$key', $dir],// 限制上传文件大小。单位:字节['content-length-range', self::ContentLengthMin, self::ContentLengthMax]]];$policyBase64 = self::getPolicyBase64($policyParams);$signature = self::getSignature($policyBase64, self::AccessKeySecret);return ['accessKeyId' => self::AccessKeyId,'host' => self::Host,'policy'=> $policyBase64,'signature' => $signature,'expire'=> $expiration,'key' => $key,'url' => self::Host . '/' . $key];}/*** 获取参数base64* @param $policyParams array* @return string*/public static function getPolicyBase64($policyParams){return base64_encode(json_encode($policyParams));}/*** 获取签名* @param $policyBase64 string* @param $accessKeySecret string* @return string*/public static function getSignature($policyBase64, $accessKeySecret){return base64_encode(hash_hmac('sha1', $policyBase64, $accessKeySecret, true));}/*** 获取过期时间* @param $time int 单位: 秒* @return mixed*/public static function getExpireTime($time){return str_replace('+00:00', '.000Z', gmdate('c', time() + $time));}/*** 获取按照月份分隔的文件夹路径* @param $dirname string eg: image/video* @return string eg: image/-10/*/public static function getDirname($dirname){return $dirname . '/' . date('Y-m') . '/';}/*** 获取一个随机的文件名* @param $ext string eg: jpg* @return string eg: a4030d9f-c4a2-4f1a-8e33-80e017e572d5.jpg* @throws \Exception*/public static function getFilename($ext){$uuid = Uuid::uuid4()->toString();return $uuid . '.' . $ext;}}

AliOssController.php

<?phpnamespace app\controller;use app\BaseController;use app\exception\AppException;use app\service\AliOssService;class AliOssController extends BaseController{public function getUploadParams(){$ext= input('ext');$dirname = input('dirname', 'image');// 参数校验if (!$ext) {throw new AppException('ext is empty');}if (!in_array($dirname, ['image', 'video'], true)) {throw new AppException('dirname: only allow image or video');}$result = AliOssService::getUploadParams(['ext'=> $ext,'dirname' => $dirname,]);return $result;}}

AppException.php

<?phpnamespace app\exception;use Exception;/*** 自定义的业务异常* Class AppException* @package app\exception*/class AppException extends Exception{}

3、微信小程序客户端

参考官网给出的示例实现

微信小程序直传实践

思路:

客户端拿到文件名后缀后,传给服务端,获取签名和文件名等必要的上传参数,让更多的工作在服务端完成

oss-upload-file.js

// 获取文件扩展名function getFilePathExtention(filePath) {return filePath.split('.').slice(-1)[0];}// 上传到阿里云ossfunction uploadFileAsync(config, filePath) {console.log(config);return new Promise((resolve, reject) => {wx.uploadFile({url: config.host, // 开发者服务器的URL。filePath: filePath,name: 'file', // 必须填file。formData: {key: config.key,policy: config.policy,OSSAccessKeyId: config.accessKeyId,signature: config.signature,// 'x-oss-security-token': securityToken // 使用STS签名时必传。},success: (res) => {console.log(res);if (res.statusCode === 204) {resolve();} else {reject('上传失败');}},fail: (err) => {// console.log(err);reject(err);},});});}// 上传文件export async function uploadFile(filePath, dirname = 'image') {console.log(filePath);let ext = getFilePathExtention(filePath);// 改方法通过接口获取服务端生成的上传签名const resParams = await Http.AliOssGetUploadParams({ext,dirname,});// console.log(resParams.data);// let objectName = resParams.data.uuid + '.' + getFilePathExtention(filePath);await uploadFileAsync(resParams.data, filePath);// console.log(res);return resParams;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。