Laravel 下设置又拍云上传图片 SDK 签名 url 的写法
这两天在用 Laravel 给微信小程序的项目写 API 接口,其中小程序端上传图片采用又拍云云存储,而官方提供了又拍云的微信小程序上传SDK,于是就直接拿来用了。
又拍云小程序SDK (Github)
关于怎样引入SDK就不说了,主要是讲一下怎样配置,如果想直接看结果,可以直接跳到页尾。
const upyun = new Upyun({
bucket: 'sdkimg', // 这里填你注册的又拍云bucket名字
operator: 'tester', // 这里填你注册的又拍云bucket名字
getSignatureUrl: 'http://localhost:8080', //这里后面会讲到
})
按照 Github 上的说明
使用又拍云微信小程序 SDK 需要实现一个在服务器进行签名的接口,并将该接口地址作为 getSignatureUrl 传入构造函数,
该接口接受 GET 请求,并接受一个参数 data,计算并返回带有 signature 字段的响应
signature 的计算公式是
Base64 (HMAC-SHA1 (, )
其中,md5_password 是操作员密码的 MD5 值
但是,折腾了半天,我也不太清楚这里面的data是一个什么样的存在。下面到了见证奇迹的时刻?
源代码分析
在官方的Github中为我们提供了一个本地的node服务器,对应的文件名是demo-server.js
。代码如下
'use strict'
const crypto = require('crypto')
const url = require('url')
const qs = require('querystring')
const http = require('http')
const md5Password = md5('grjxv2mxELR3')
console.log('password md5', md5Password)
const server = http.createServer((req, res) => {
const query = qs.parse(url.parse(req.url).query)
console.log('query', query)
const signature = base64Sha1(query.data, md5Password)
console.log('signature', signature)
res.writeHead(200, {
'Content-Type': 'application/json'
})
res.end(JSON.stringify({signature}))
})
server.listen(8080, () => {
console.log('Server listen on http://localhost:8080')
})
function md5 (str) {
return crypto.createHash('md5').update(str, 'utf8').digest('hex')
}
function base64Sha1 (str, secret) {
return crypto.createHmac('sha1',secret).update(str,'utf8').digest().toString('base64')
}
在上面代码中,可以看到SDK调用上传时会传入一些参数,然后再进行加密。我们再找到upyun-wxapp-sdk.js
文件中第42行开始,代码如下
Upyun.prototype.getSignature = function (data, cb) {
wx.request({
url: this.getSignatureUrl,
data: {
data: data
},
success: function (res) {
cb(null, res.data.signature)
},
fail: function (err) {
cb(err)
}
})
}
可以看出,又拍云SDK会获取getSignatureUrl的地址,并对这个地址发起get请求,同时传递data参数,继而在demo-server.js
文件中进行相关的加密处理。熟悉了这个过程之后,我们Laravel端的代码写起来也就比较简单了。
Laravel 代码
// routes/api.php 路由
//这里我使用了dingo/api的包,因此是$api->的写法,未使用的可直接更换为常规写法即可
$api->get('signature', 'UtilsController@upSignature'); // 返回又拍云的验证
// UtilsController.php 控制器代码
<?php
namespace App\Http\Controllers;
class UtilsController extends Controller
{
public function upSignature()
{
/*
* config('upyun.operator.password') 为又拍云的operator的密码
* 这里可以直接改为密码字符串,不过为了更加保密和灵活,我写成了配置文件。
* 然后在env中可以动态配置
*/
$md5Password = md5(config('upyun.operator.password'));
$signature = base64_encode(hash_hmac("sha1", request()->data, $md5Password, true));
return ['signature' => $signature];
}
}
// config/upyun.php
<?php
return [
'operator' => [
'name' => env('UPYUN_OPERATOR_NAME', ''),
'password' => env('UPYUN_OPERATOR_PASSWORD', ''),
]
];
然后将写好的signature地址替换掉getSignatureUrl里的http://localhost:8080
就可以上传成功了。
其实,我写这篇文章的目的是与其看文档,Google搜索半天,还不如我看源码解决问题来的快??
本作品采用《CC 协议》,转载必须注明作者和本文链接