Files
EventHubBack/src/logic/logic_auth.erl
2026-04-20 10:28:53 +03:00

88 lines
2.3 KiB
Erlang
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-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}.