以前写安卓使用到了七牛进行图片上传获取外链,在网上搜索token的获取方法,都没有一个可靠一点的,各种模拟获取token..连官方文档也写着token加密方法不属于androidSDK文档范畴...
于是这次,本着学习javaweb的心态,花了一晚上的时间把官方服务器端sdk看了下,了解了加密方式,制作出了java后端token获取工具。虽然只有最基础的功能,但也算够用了,以后如果有需求再增加功能,欢迎大家star,fork
由于accessKey这些数据很重要,这里我也为大家把核心代码和步骤分享出来供大家自己在服务器上使用。
上图是比较清晰的上传思路,一共有五步,涉及到Base64和HMAC-SHA1加密
测试数据:
Bucket: "qtestbucket",
AK: "iN7NgwM31j4-BZacMjPrOQBs34UG1maYCAQmhdCV",
SK: "6QTOr2Jg1gcZEWDQXKOGZh5PziC2MCV5KsntT70j"
接下来一步一步用java代码演示
-
序列化上传策略
上传策略在官方sdk文档上有,最基本的两条是scope和deadline,对应着bucket名字和截止日期。将上传策略序列化为json格式
{ "scope" : "qtestbucket", "deadline" : 1519389163 }
//截止期限,这里设置一个小时,值越大越长,php格式的10位数值 long deadline = System.currentTimeMillis() / 1000L + get1Hour(); //序列化为String类型(jsonEncoder是个傻傻的json参数拼接方法) String s = jsonEncoder(bucket, String.valueOf(deadline));
-
编码上传策略
对上传策略(json)使用Base64编码,得到encoded
//Base64编码使用java内置的也行,这里我使用的七牛sdk里的Base64类 Base64.encodeToString(data, 10);
-
HMAC-SHA1加密
使用encoded对SecretKey进行HMAC-SHA1加密,将加密结果进行Base64编码,得到encode_signed
这里有点坑,网上java的HMAC-SHA1加密方式似乎无法得到正确的结果,官方sdk的加密方式才行。
private String sign(byte[] data) { //HMAC-SHA1加密 Mac mac = this.createMac(); //将HMAC-SHA1加密结果进行Base64编码 String encodedSign = encodeToString(mac.doFinal(data)); //得到encode_signed,返回拼接 return this.accessKey + ":" + encodedSign; } //Base64编码 private static String encodeToString(byte[] data) { return Base64.encodeToString(data, 10); } //HMAC-SHA1加密 private Mac createMac() { try { Mac mac = Mac.getInstance("HmacSHA1"); mac.init(this.secretKey); return mac; } catch (GeneralSecurityException var3) { var3.printStackTrace(); throw new IllegalArgumentException(var3); } }
-
拼接
将AccessKey,encode_signed,encoded使用“:”拼接,得到最终token
所有和获取token有关的代码在Util文件夹内,可自行下载使用,使用方法如下
TokenHelper tokenHelper = TokenHelper.create(accessKey, secretKey);
String token = tokenHelper.getToken(bucket);
至于为啥我写的TokenHelper代码如此混乱,因为我抄袭了官方sdk的代码风格...
官方的Auth类一样的各种return,还没注释=_=
为了拼接,类似return this.accessKey + ":" + encodedSign
这样的方式让代码稍微绕了点。
最后把打包后的war包发出来qiniu.war