Time zone is crucial for One Time Password
Developing two factor authentication, I got an error where the password didn’t pass, even though the logic was right.
The logic
# Ruby
def create
if current_user.validate_and_consume_otp!(params[:otp_attempt])
current_user.otp_required_for_login = true
current_user.save!
redirect_to root_path
else
@error = 'Invalid pin code'
@qr_code = build_qr_code
render 'new'
end
end
This code checks if the user is correct by executing validate_and_consume_otp! method, but it was always false.
The reason
The timezone of the server and my smartphone’s timezone were different, therefore, the validation didn’t pass. I resolved the error by adjusting the time.
How One Time Password works?
There are two types of one time password.
TOTP (Time-based One-Time Password):
In this method, OTP is generated based on time. For example, the user and the server share a common “secret key,” and the password is generated using that key along with the current time. TOTP generates a new password at regular intervals, and the password remains valid for a certain period. TOTP is used in apps like Google Authenticator and Microsoft Authenticator.
HOTP (HMAC-based One-Time Password):
In this method, OTP is generated based on a counter. The user and the server share a common “secret key,” and the password is generated using that key along with an incrementing counter. After each login, the counter increases, and the OTP is generated based on the current counter and the secret key.
Popular authenticators such as Google Authenticator, Microsoft Authenticator are using TOTP algorithm. That’s why, the error happened.
How about global services such as AWS?
However, in some services, it is hard for servers and clients to be in the same timezone. In this case, we use UTC to adjust the time.