Skip to content

Commit e0b110d

Browse files
committed
Merge pull request #3 from okeuday/master
Fix signature usage.
2 parents 9f5f519 + 35e3944 commit e0b110d

File tree

1 file changed

+46
-51
lines changed

1 file changed

+46
-51
lines changed

src/jwt.erl

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,66 +3,61 @@
33

44
-include("jwt.hrl").
55

6+
%%%------------------------------------------------------------------------
7+
%%% External interface functions
8+
%%%------------------------------------------------------------------------
9+
610
encode(Algorithm, Payload, Secret) ->
711
encode(Algorithm, Payload, Secret, []).
812

913
encode(Algorithm, Payload, Secret, HeaderExtra) ->
1014
AlgorithmName = atom_to_algorithm(Algorithm),
11-
Header = jsx:encode([{typ, <<"JWT">>}, {alg, AlgorithmName}|HeaderExtra]),
12-
PayloadJson = jsx:encode(Payload),
13-
Signature = get_signature(Algorithm, PayloadJson, Secret),
14-
Parts = [Header, PayloadJson, Signature],
15-
EncodedParts = [base64url:encode(Item) || Item <- Parts],
16-
JwtData = bin_join(EncodedParts, <<".">>),
17-
{ok, JwtData}.
15+
Header = jsx:encode([{typ, <<"JWT">>},
16+
{alg, AlgorithmName} | HeaderExtra]),
17+
HeaderEncoded = base64url:encode(Header),
18+
PayloadEncoded = base64url:encode(jsx:encode(Payload)),
19+
DataEncoded = <<HeaderEncoded/binary, $., PayloadEncoded/binary>>,
20+
Signature = get_signature(Algorithm, DataEncoded, Secret),
21+
SignatureEncoded = base64url:encode(Signature),
22+
{ok, <<DataEncoded/binary, $., SignatureEncoded/binary>>}.
1823

1924
decode(Data, Secret) when is_binary(Data) ->
20-
Parts = binary:split(Data, [<<".">>], [global]),
21-
try
22-
DecodedParts = [base64url:decode(Item) || Item <- Parts],
23-
24-
if
25-
length(DecodedParts) < 3 ->
26-
{error, badtoken};
27-
true ->
28-
[HeaderJson,BodyRaw,Signature|_Tail] = DecodedParts,
29-
Header = jsx:decode(HeaderJson),
30-
AlgorithmStr = proplists:get_value(<<"alg">>, Header),
31-
Expiration = proplists:get_value(<<"exp">>, Header, noexp),
32-
Algorithm = algorithm_to_atom(AlgorithmStr),
33-
34-
Type = proplists:get_value(<<"typ">>, Header),
35-
36-
ActualSignature = get_signature(Algorithm, BodyRaw, Secret),
37-
38-
Jwt = #jwt{typ=Type, body=BodyRaw, alg=Algorithm,
39-
sig=Signature, actual_sig=ActualSignature},
40-
41-
if
42-
Signature =:= ActualSignature ->
43-
% TODO: leeway
44-
NowSecs = now_secs(),
45-
if Expiration == noexp orelse Expiration > NowSecs ->
25+
try binary:split(Data, [<<".">>], [global]) of
26+
[HeaderEncoded, PayloadEncoded, SignatureEncoded] ->
27+
Header = jsx:decode(base64url:decode(HeaderEncoded)),
28+
Type = proplists:get_value(<<"typ">>, Header),
29+
AlgorithmStr = proplists:get_value(<<"alg">>, Header),
30+
Expiration = proplists:get_value(<<"exp">>, Header, noexp),
31+
Algorithm = algorithm_to_atom(AlgorithmStr),
32+
DataEncoded = <<HeaderEncoded/binary, $., PayloadEncoded/binary>>,
33+
ActualSignature = get_signature(Algorithm, DataEncoded, Secret),
34+
Signature = base64url:decode(SignatureEncoded),
35+
Payload = jsx:decode(base64url:decode(PayloadEncoded)),
36+
Jwt = #jwt{typ=Type, body=Payload, alg=Algorithm,
37+
sig=Signature, actual_sig=ActualSignature},
38+
if
39+
Signature =:= ActualSignature ->
40+
% TODO: leeway
41+
NowSecs = now_secs(),
42+
if
43+
Expiration == noexp orelse Expiration > NowSecs ->
4644
{ok, Jwt};
47-
true ->
48-
{error, {expired, Expiration}}
49-
end;
50-
51-
true ->
52-
{error, {badsig, Jwt}}
53-
end
54-
end
55-
catch error:E ->
56-
{error, E}
45+
true ->
46+
{error, {expired, Expiration}}
47+
end;
48+
true ->
49+
{error, {badsig, Jwt}}
50+
end;
51+
_ ->
52+
{error, badtoken}
53+
catch
54+
error:E ->
55+
{error, E}
5756
end.
5857

59-
%% private
60-
61-
bin_join(Items, Sep) ->
62-
lists:foldl(fun (Val, <<>>) -> Val;
63-
(Val, Accum) ->
64-
<<Accum/binary, Sep/binary, Val/binary>>
65-
end, <<>>, Items).
58+
%%%------------------------------------------------------------------------
59+
%%% Private functions
60+
%%%------------------------------------------------------------------------
6661

6762
algorithm_to_atom(<<"HS256">>) -> hs256;
6863
algorithm_to_atom(<<"HS384">>) -> hs384;
@@ -78,7 +73,7 @@ algorithm_to_crypto_algorithm(hs512) -> sha512.
7873

7974
get_signature(Algorithm, Data, Secret) ->
8075
CryptoAlg = algorithm_to_crypto_algorithm(Algorithm),
81-
crypto:hmac(CryptoAlg, Data, Secret).
76+
crypto:hmac(CryptoAlg, Secret, Data).
8277

8378
now_secs() ->
8479
{MegaSecs, Secs, _MicroSecs} = os:timestamp(),

0 commit comments

Comments
 (0)