按照文档上讲解的一步步生成token后,测试上传一直失败,提示是401 bad token ,错误是很明显了,可是我检查好久了,真不知问题出在哪里了?我贴出生成token的代码:
public static String getUploadToken(String fileName) {
String token = null;
try{
//一:将上传策略转换成Json格式
JSONObject policy = new JSONObject();
StringBuilder scope = new StringBuilder();
scope.append(bucket);
scope.append(":");
scope.append(fileName);
policy.put("scope",scope.toString()); //只允许上传指定key的文件,而key就是文件名
scope = null;
policy.put("deadline",getTimer());
//policy.put("insertOnly",1); //不允许修改
//policy.put("callbackFetchKey",1); //启动fetchKey上传模式
// policy.put("returnBody ","{\"name\" : \"$(fname))}");
Log.d("policy",policy.toString());
//二:对JSON编码的上传策略进行URL安全的Base64编码,得到待签名字符串:
String encodPutPolicy = Base64.encodeToString(policy.toString().getBytes("UTF-8"), Base64.URL_SAFE);
Log.i("encodPutPolicy","encodPutPolicy is " + encodPutPolicy);
//三:使用SecertKey对上一步生成的待签名字符串计算HMAC-SHA1签名:并对签名进行URL安全的Base64编码:
String encodSign = hmac_sha1(SK,encodPutPolicy);
Log.i("encodSign","encodSign is " + encodSign);
//五:将AccessKey、encodedSign和encodedPutPolicy用:连接起来:
token = AK + ':' + encodSign + ':' + encodPutPolicy;
Log.i("token","token is " + token);
}catch (Exception e) {
e.printStackTrace();
}
return token;
}
private static long getTimer() {
return System.currentTimeMillis() + 3600; //上传凭证的有效期
}
//对字符串进行HMAC-SHA1签名
private static String hmac_sha1(String key,String message) {
String reString = null;
try {
byte[] data = key.getBytes("UTF-8");
//根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
SecretKey secretKey = new SecretKeySpec(data, "HmacSHA1");
//生成一个指定 Mac 算法 的 Mac 对象
Mac mac = Mac.getInstance("HmacSHA1");
//用给定密钥初始化 Mac 对象
mac.init(secretKey);
byte[] text = message.getBytes("UTF-8");
//完成 Mac 操作
byte[] text1 = mac.doFinal(text);
reString = Base64.encodeToString(text1, Base64.URL_SAFE);
} catch (Exception e)
{
e.printStackTrace();
}
return reString;
}
其中AK和SK分别是我七牛空间的AccessKey和SecretKey.
Base64用的是 com.loopj.android.http.Base64;包的。我是哪里还没有符合规范吗?
不应该在 android app 里面去生成 uptoken。原因是:不能把 SecretKey 放到客户端软件中,这会导致你的存储空间存在被他人访问的风险。正确做法是,应该由你的服务器生成 uptoken 然后返回给 android 客户端。