本文为 veImageX 不同语言的 URL 鉴权 Demo 示例。
func getMD5(s string) string { h := md5.New() h.Write([]byte(s)) return hex.EncodeToString(h.Sum(nil)) } // 鉴权方式A func authA(domain, path, secretKey, signParam string) string { u := url.URL{ Scheme: "http", // 支持 http、https Host: domain, Path: path, } ts := time.Now().Unix() rand := "rand" // 随机字符串,默认值为 "rand"。 uid := "imagex" // 用户 ID,默认值为 "imagex"。 //path + timestamp + rand + uid + key signTxt := fmt.Sprintf("%s-%d-%s-%s-%s", u.EscapedPath(), ts, rand, uid, secretKey) sign := fmt.Sprintf("%d-%s-%s-%s", ts, rand, uid, getMD5(signTxt)) q := url.Values{ signParam: []string{sign}, } u.RawQuery = q.Encode() return u.String() } // 鉴权方式B func authB(domain, path, secretKey string) string { u := url.URL{ Scheme: "http", // 支持 http、https Host: domain, Path: path, } tn := time.Now() tStr := tn.Format("200601021504") //key + tStr + path signTxt := fmt.Sprintf("%s%s%s", secretKey, tStr, u.EscapedPath()) sign := getMD5(signTxt) u.Path = fmt.Sprintf("/%s/%s%s", tStr, sign, path) return u.String() } // 鉴权方式C func authC(domain, path, secretKey string) string { u := url.URL{ Scheme: "http", // 支持 http、https Host: domain, Path: path, } ts := time.Now().Unix() //key + path + hex(ts) signTxt := fmt.Sprintf("%s%s%x", secretKey, u.EscapedPath(), ts) sign := getMD5(signTxt) u.Path = fmt.Sprintf("/%s/%x%s", sign, ts, path) return u.String() } // 鉴权方式D func authD(domain, path, secretKey, signParam, timestampFormat, timestampParam string) string { u := url.URL{ Scheme: "http", // 支持 http、https Host: domain, Path: path, } ts := time.Now().Unix() tsStr := fmt.Sprintf("%d", ts) if timestampFormat == "hex" { tsStr = fmt.Sprintf("%x", ts) } //key + path + ts signTxt := fmt.Sprintf("%s%s%s", secretKey, u.EscapedPath(), tsStr) sign := getMD5(signTxt) q := url.Values{ signParam: []string{sign}, timestampParam: []string{tsStr}, } u.RawQuery = q.Encode() return u.String() } func main() { domain := "example.volcimagex.cn" uri := "<input resource uri>" tpl := "input resource template" format := "input output image format" // 图片资源 path := fmt.Sprintf("/%s~%s.%s", uri, tpl, format) // 素材托管 //path = fmt.Sprintf("/%s", uri) signParam := "<input sign parameter key>" mainSecretKey := "<input secret key>" u := authA(domain, path, mainSecretKey, signParam) fmt.Println("URL: ", u) u = authB(domain, path, mainSecretKey) fmt.Println("URL: ", u) u = authC(domain, path, mainSecretKey) fmt.Println("URL: ", u) timeParam := "<input timestamp parameter key>" //十进制 or 十六进制 timeFormat := "<input timestamp format>" u = authD(domain, path, mainSecretKey, signParam, timeFormat, timeParam) fmt.Println("URL: ", u) }
import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.time.Instant; import java.util.Date; import java.util.TimeZone; public class URLSigner { private String getHex(byte[] raw) { if (raw == null) { return null; } final StringBuilder hex = new StringBuilder(2 * raw.length); for (final byte b : raw) { String HEXES = "0123456789abcdef"; hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F))); } return hex.toString(); } private String getMd5(String data) { String ret; try { MessageDigest h = MessageDigest.getInstance("md5"); byte[] digest = h.digest(data.getBytes(StandardCharsets.UTF_8)); ret = getHex(digest); } catch (Exception e) { throw new RuntimeException(e); } return ret; } SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); { formatter.setTimeZone(TimeZone.getTimeZone("UTC")); } /** * 鉴权方式 A */ public String authA(String domain, String path, String secretKey, String nonce, String uid, String parameterName) { long ts = (Instant.now().getEpochSecond()); String signText = String.format("%s-%d-%s-%s-%s", path, ts, nonce, uid, secretKey); String sign = getMd5(signText); String signValue = String.format("%d-%s-%s-%s", ts, nonce, uid, sign); return String.format("https://%s%s?%s=%s", domain, path, parameterName, signValue); } /** * 鉴权方式 B */ public String authB(String domain, String path, String secretKey) { Instant ts = Instant.now(); String tStr = formatter.format(new Date(Timestamp.from(ts).getTime())); String signText = String.format("%s%s%s", secretKey, tStr, path); String sign = getMd5(signText); String signPath = String.format("/%s/%s", tStr, sign); return String.format("https://%s%s%s", domain, signPath, path); } /** * 鉴权方式 C */ public String authC(String domain, String path, String secretKey) { long ts = (Instant.now().getEpochSecond()); String signText = String.format("%s%s%x", secretKey, path, ts); String sign = getMd5(signText); String signPath = String.format("/%s/%x", sign, ts); return String.format("https://%s%s%s", domain, signPath, path); } /** * 鉴权方式 D */ public String authD(String domain, String path, String secretKey, String signParameterName, boolean timestampFormatInHex, String timestampParameterName) { long ts = (Instant.now().getEpochSecond()); String tsStr = "" + ts; if (timestampFormatInHex) { tsStr = String.format("%x", ts); } String signText = String.format("%s%s%s", secretKey, path, tsStr); String sign = getMd5(signText); return String.format("https://%s%s?%s=%s&%s=%s", domain, path, signParameterName, sign, timestampParameterName, tsStr); } private void run() { String domain = "example.volcimagex.cn"; String key = "<input secret key>"; String path = "<input file path>"; System.out.println(authA(domain, path, key, "anything_you_like", "anything_you_like", "sign")); System.out.println(authB(domain, path, key)); System.out.println(authC(domain, path, key)); System.out.println(authD(domain, path, key, "sign", false, "time")); System.out.println(authD(domain, path, key, "sign", true, "time")); } public static void main(String[] args) { URLSigner signer = new URLSigner(); signer.run(); } }
import hashlib import time from datetime import datetime from requests.models import PreparedRequest def get_md5(s): m = hashlib.md5() m.update(s.encode('utf-8')) return m.hexdigest() # 鉴权方式A def auth_a(domain, path, secret_key, sign_param): ts = int(time.time()) rand = "rand" # "rand" by default, any value you defined is ok uid = "imagex" # "imagex" by default, any value you defined is ok signTxt = f"{path}-{ts}-{rand}-{uid}-{secret_key}" sign = get_md5(signTxt) sign_value = f"{ts}-{rand}-{uid}-{sign}" return f"http://{domain}{path}?{sign_param}={sign_value}" # 鉴权方式B def auth_b(domain, path, secret_key): cur_time = datetime.today().strftime("%Y%m%d%H%M") sign = get_md5(f"{secret_key}{cur_time}{path}") sign_path = f"/{cur_time}/{sign}" return f"http://{domain}{sign_path}{path}" # 鉴权方式C def auth_c(domain, path, secret_key): ts = int(time.time()) signTxt = f"{secret_key}{path}{ts}" sign = get_md5(signTxt) sign_path = f"/{sign}/{ts}" return f"http://{domain}{sign_path}{path}" # 鉴权方式D def auth_d(domain, path, secret_key, sign_param, timestamp_format, timestamp_param): ts = int(time.time()) tsStr = "%x" %(ts) if timestamp_format == "hex" else "%d" % (ts) signTxt = f"{secret_key}{path}{tsStr}" sign = get_md5(signTxt) params = {sign_param: sign, timestamp_param: tsStr} url = f"http://{domain}{path}" req = PreparedRequest() req.prepare_url(url, params) return req.url def main(): domain = "example.volcimagex.cn" uri = "<input resource uri>" tpl = "input resource template" format = "input output image format" path = f"/{uri}~{tpl}.{format}" # 图片资源 #path = f"/{uri}" #素材托管 sign_param = "<input sign parameter key>" mainsecret_key = "<input secret key>" u = auth_a(domain, path, mainsecret_key, sign_param) print("URL: ", u) u = auth_b(domain, path, mainsecret_key) print("URL: ", u) u = auth_c(domain, path, mainsecret_key) print("URL: ", u) timeParam = "<input timestamp parameter key>" timeFormat = "<input timestamp format>" #十进制 or 十六进制 u = auth_d(domain, path, mainsecret_key, sign_param, timeFormat, timeParam) print("URL: ", u) if __name__ == "__main__": main()
<?php namespace Volc\Service\ImageX; class Signer { public $scheme = "https:"; /** * 鉴权方式 A */ public function authA(string $domain, string $path, string $secretKey, string $nonce, string $uid, string $parameterName) { $ts = time(); $signText = sprintf("%s-%d-%s-%s-%s", $path, $ts, $nonce, $uid, $secretKey); $sign = strtolower(md5($signText)); $signValue = sprintf("%d-%s-%s-%s", $ts, $nonce, $uid, $sign); return sprintf("%s//%s%s?%s=%s", $this->scheme, $domain, $path, $parameterName, $signValue); } /** * 鉴权方式 B */ public function authB(string $domain, string $path, string $secretKey) { $ts = time(); $tStr = date("YmdHis", $ts); $signText = sprintf("%s%s%s", $secretKey, $tStr, $path); $sign = strtolower(md5($signText)); $signPath = sprintf("/%s/%s", $tStr, $sign); return sprintf("%s//%s%s%s", $this->scheme, $domain, $signPath, $path); } /** * 鉴权方式 C */ public function authC(string $domain, string $path, string $secretKey) { $ts = time(); $signText = sprintf("%s%s%x", $secretKey, $path, $ts); $sign = strtolower(md5($signText)); $signPath = sprintf("/%s/%x", $sign, $ts); return sprintf("%s//%s%s%s", $this->scheme, $domain, $signPath, $path); } /** * 鉴权方式 D */ public function authD(string $domain, string $path, string $secretKey, string $signParameterName, bool $timestampFormatInHex, string $timestampParameterName) { $ts = time(); if ($timestampFormatInHex) { $tsStr = sprintf("%08x", $ts); } else { $tsStr = sprintf("%d", $ts); } $signText = sprintf("%s%s%s", $secretKey, $path, $tsStr); $sign = strtolower(md5($signText)); return sprintf("%s//%s%s?%s=%s&%s=%s", $this->scheme, $domain, $path, $signParameterName, $sign, $timestampParameterName, $tsStr); } private function run() { $domain = "example.volcimagex.cn"; $key = "<input secret key>"; $path = "<input file path>"; echo($this->authA($domain, $path, $key, "anything_you_like", "anything_you_like", "sign")); echo("\n"); echo($this->authB($domain, $path, $key)); echo("\n"); echo($this->authC($domain, $path, $key)); echo("\n"); echo($this->authD($domain, $path, $key, "sign", false, "time")); echo("\n"); echo($this->authD($domain, $path, $key, "sign", true, "time")); } public static function main() { $signer = new static; $signer->run(); } } if ($argv && $argv[0] && realpath($argv[0]) === __FILE__) { Signer::main(); }
const crypto = require('crypto'); const moment = require('moment'); function getMd5(s) { return crypto.createHash('md5').update(s, 'utf-8').digest('hex'); } // 鉴权方式A function authA(domain, path, secretKey, signParam) { const ts = Math.floor(Date.now() / 1000); const rand = "rand"; // "rand" by default, any value you defined is ok const uid = "imagex"; // "imagex" by default, any value you defined is ok const signTxt = `${encodeURI(path)}-${ts}-${rand}-${uid}-${secretKey}`; const sign = getMd5(signTxt); const signValue = `${ts}-${rand}-${uid}-${sign}`; return `http://${domain}${encodeURI(path)}?${signParam}=${signValue}`; } // 鉴权方式B function authB(domain, path, secretKey) { const curTime = moment().format("YYYYMMDDHHmm"); const sign = getMd5(`${secretKey}${curTime}${encodeURI(path)}`); const signPath = `/${curTime}/${sign}`; return `http://${domain}${signPath}${encodeURI(path)}`; } // 鉴权方式C function authC(domain, path, secretKey) { const ts = Math.floor(Date.now() / 1000).toString(16); const signTxt = `${secretKey}${encodeURI(path)}${ts}`; console.log(signTxt, ts, encodeURI(path)) const sign = getMd5(signTxt); const signPath = `/${sign}/${ts}`; return `http://${domain}${signPath}${encodeURI(path)}`; } // 鉴权方式D function authD(domain, path, secretKey, signParam, timestampFormat, timestampParam) { const ts = Math.floor(Date.now() / 1000); const tsStr = timestampFormat === "hex" ? ts.toString(16) : ts.toString(); const signTxt = `${secretKey}${encodeURI(path)}${tsStr}`; const sign = getMd5(signTxt); const params = { [signParam]: sign, [timestampParam]: tsStr }; const url = new URL(`http://${domain}${path}`); url.search = new URLSearchParams(params).toString(); return url.toString(); } function main() { const domain = "example.volcimagex.cn"; const uri = "<input resource uri>"; const tpl = "input resource template"; const format = "input output image format"; const path = `/${uri}~${tpl}.${format}`; // 图片资源 // const path = `/${uri}`; // 素材托管 const signParam = "<input sign parameter key>"; const mainSecretKey = "<input secret key>"; let u = authA(domain, path, mainSecretKey, signParam); console.log("URL: ", u); u = authB(domain, path, mainSecretKey); console.log("URL: ", u); u = authC(domain, path, mainSecretKey); console.log("URL: ", u); const timeParam = "<input timestamp parameter key>"; const timeFormat = "<input timestamp format>"; // 十进制 or 十六进制 u = authD(domain, path, mainSecretKey, signParam, timeFormat, timeParam); console.log("URL: ", u); } main();