diff --git a/apps/sdlan/src/sdlan_api.erl b/apps/sdlan/src/sdlan_api.erl index dad76ea..cea985f 100644 --- a/apps/sdlan/src/sdlan_api.erl +++ b/apps/sdlan/src/sdlan_api.erl @@ -9,7 +9,7 @@ -module(sdlan_api). -author("anlicheng"). --define(API_TOKEN, <<"wv6fGyBhl*7@AsD9">>). +-define(API_TOKEN, <<"H6p*2RfEu4ITcL">>). %% API -export([get_all_networks/0, get_network/1]). @@ -104,12 +104,11 @@ network_forward_report(NetworkId, ForwardNum) when is_integer(NetworkId), is_int -spec do_get(Uri :: string(), Params :: [{K :: binary(), V :: binary()}]) -> {ok, Response :: binary()} | {error, Reason :: any()}. do_get(Uri, Params) when is_list(Uri), is_list(Params) -> - Token = sdlan_util:md5(<>), {ok, Url0} = application:get_env(sdlan, api_url), Headers = [ - {<<"content-type">>, <<"application/json">>}, - {<<"token">>, Token} + {<<"Content-Type">>, <<"application/json">>}, + {<<"X-sign">>, sign_params(Params)} ], QS0 = uri_string:compose_query(Params), @@ -129,14 +128,13 @@ do_get(Uri, Params) when is_list(Uri), is_list(Params) -> {error, Reason} end. --spec do_post(Uri :: string(), Params :: list() | map()) -> {ok, Resp :: binary()} | {error, Reason :: any()}. -do_post(Uri, Params) when is_list(Uri), is_map(Params); is_list(Params) -> - Token = sdlan_util:md5(<>), +-spec do_post(Uri :: string(), Params :: map()) -> {ok, Resp :: binary()} | {error, Reason :: any()}. +do_post(Uri, Params) when is_list(Uri), is_map(Params) -> {ok, Url0} = application:get_env(sdlan, api_url), Headers = [ {<<"content-type">>, <<"application/json">>}, - {<<"token">>, Token} + {<<"X-sign">>, sign_params(Params)} ], Body = iolist_to_binary(jiffy:encode(Params, [force_utf8])), @@ -158,4 +156,33 @@ do_post(Uri, Params) when is_list(Uri), is_map(Params); is_list(Params) -> {error, <<"empty response">>}; {error, Reason} -> {error, Reason} - end. \ No newline at end of file + end. + +-spec sign_params(Params :: any()) -> binary(). +sign_params(Params) when is_list(Params) -> + %% 签名逻辑 + Keys = lists:map(fun({K, _}) -> K end, Params), + Parts = lists:map(fun(K) -> + V = as_binary(proplists:get_value(K, Params, <<"">>)), + <>, Parts)), + list_to_binary(sdlan_util:hmac(?API_TOKEN, SignBin)); +sign_params(Params) when is_map(Params) -> + SortedKeys = lists:sort(maps:keys(Params)), + Parts = lists:map(fun(K) -> + V = as_binary(maps:get(K, Params, <<"">>)), + <>, Parts)), + list_to_binary(sdlan_util:hmac(?API_TOKEN, SignBin)). + +-spec as_binary(Bin :: any()) -> binary(). +as_binary(Bin) when is_binary(Bin) -> + Bin; +as_binary(I) when is_integer(I) -> + integer_to_binary(I); +as_binary(F) when is_float(F) -> + float_to_binary(F, [short]); +as_binary(Str) when is_list(Str) -> + list_to_binary(Str). \ No newline at end of file diff --git a/apps/sdlan/src/sdlan_util.erl b/apps/sdlan/src/sdlan_util.erl index 2d42bda..f95bcbc 100644 --- a/apps/sdlan/src/sdlan_util.erl +++ b/apps/sdlan/src/sdlan_util.erl @@ -15,6 +15,7 @@ -export([is_broadcast_mac/1, is_multicast_mac/1]). -export([ipv4_to_int/1, int_to_ipv4/1, ips/2, format_ip/1]). -export([ipv6_bytes_to_binary/1]). +-export([hmac/2]). -spec format_mac(Mac :: binary()) -> binary(). format_mac(Mac) when is_binary(Mac) -> @@ -115,4 +116,10 @@ ipv6_bytes_to_binary(<>) -> % 合并成IPv6地址格式,这里没有处理最简化形式的缩写 iolist_to_binary(lists:flatten(string:join(Padded, ":"))); ipv6_bytes_to_binary(_) -> - <<"">>. \ No newline at end of file + <<"">>. + +-spec hmac(Key :: binary(), Data :: binary()) -> string(). +hmac(Key, Data) when is_binary(Key), is_binary(Data) -> + Digest = crypto:mac(hmac, md5, Key, Data), + %% 转成十六进制小写字符串,和 PHP hash_hmac 一致 + lists:flatten([io_lib:format("~2.16.0b", [B]) || B <- binary:bin_to_list(Digest)]). \ No newline at end of file