This commit is contained in:
2026-04-20 10:28:53 +03:00
parent 7e776ea6e3
commit 4224da1a22
11 changed files with 520 additions and 6 deletions

88
src/logic/logic_auth.erl Normal file
View File

@@ -0,0 +1,88 @@
-module(logic_auth).
-export([hash_password/1, verify_password/2]).
-export([generate_jwt/2, verify_jwt/1, extract_claims/1]).
-export([generate_refresh_token/1]).
%% ============ Argon2 хеширование ============
hash_password(Password) when is_binary(Password) ->
argon2:hash(Password).
verify_password(Password, Hash) when is_binary(Password), is_binary(Hash) ->
argon2:verify(Password, Hash).
%% ============ JWT с использованием jose ============
get_jwt_secret() ->
<<"my-super-secret-key-for-jwt-32-bytes!">>.
get_jwk() ->
jose_jwk:from_oct(get_jwt_secret()).
generate_jwt(UserId, Role) ->
JWK = get_jwk(),
ExpTime = os:system_time(seconds) + 86400, % 24 часа
Claims = #{
<<"user_id">> => UserId,
<<"role">> => Role,
<<"exp">> => ExpTime,
<<"iat">> => os:system_time(seconds)
},
JWT = jose_jwt:sign(JWK, #{<<"alg">> => <<"HS256">>}, Claims),
{_, Token} = jose_jws:compact(JWT),
Token.
verify_jwt(Token) when is_binary(Token) ->
try
JWK = get_jwk(),
case jose_jwt:verify(JWK, Token) of
{true, {jose_jwt, Claims}, _} ->
case check_expiry(Claims) of
true -> {ok, Claims};
false -> {error, expired}
end;
{true, Claims, _} when is_map(Claims) ->
case check_expiry(Claims) of
true -> {ok, Claims};
false -> {error, expired}
end;
{false, _, _} ->
{error, invalid_signature}
end
catch
_:_ -> {error, invalid_token}
end.
extract_claims(Token) when is_binary(Token) ->
try
JWK = get_jwk(),
case jose_jwt:verify(JWK, Token) of
{true, {jose_jwt, Claims}, _} ->
{ok, Claims};
{true, Claims, _} when is_map(Claims) ->
{ok, Claims};
_ ->
{error, invalid_token}
end
catch
_:_ -> {error, invalid_token}
end.
check_expiry(Claims) ->
case maps:find(<<"exp">>, Claims) of
{ok, Exp} when is_integer(Exp) ->
Exp > os:system_time(seconds);
_ ->
false
end.
%% ============ Refresh Token ============
generate_refresh_token(_UserId) ->
Token = base64:encode(crypto:strong_rand_bytes(32)),
ExpiresAt = calendar:universal_time_to_local_time(
calendar:gregorian_seconds_to_datetime(
calendar:datetime_to_gregorian_seconds(calendar:universal_time()) + 30 * 86400
)
),
{Token, ExpiresAt}.