Двухфакторная аутентификация с Рубином (посредством разработки)
Я собираюсь добавить два фактора аутентификации для моего приложения Ruby. Мне нужна действительно простая реализация его с простыми случаями использования:
Возможность генерировать и отправлять коды по sms или электронной почте (значит, я не хочу быть прикрепленным к Google Authenticator с этим);
-
Возможность показать сначала форму логин-пароль, а затем форму для кода (так же, как это делает сейчас github).
Пока не похоже на ракетостроение. Но почему-то я застрял.
Итак, мой вопрос в следующем: пытался ли кто-нибудь реализовать это, и если да, то какую стратегию вы использовали для этого?
Я пробовал использовать devise-two-factor
драгоценный камень, который описывается как "двухфакторная аутентификация Barebones с Devise".
Под капотом он аутентифицирует пользователя с помощью логина + пароля+кода (все одновременно). Но в моем случае я хочу, чтобы пользователь сначала ввел логин+пароль (с помощью формы posting), а затем отправил код пользователю, прежде чем пользователь затем введет код позже, на следующее окно.
Единственное решение, которое я нашел, - это хранить логин и пароль в сеансе (sic!) и использовать для аутентификации пользователя после того, как он ввел 2-факторный код. Я не слишком уверен в этой стратегии.
3 ответа:
Devise-two-factor-это мнение о том, как должен работать Ваш логин. Я думаю, что вам лучше использоватьROTP gem напрямую (который использует devise-two-factor) и реализовать пользовательское решение.
Рики у Twilio здесь.
Мы построили приложение для двухфакторной аутентификации в Ruby, которое вы можете проверить, если ищете вдохновение. Наше приложение использует Authy, и есть пара связанных битов в коде, чтобы начать это.
Во-первых, при создании нового пользователя необходимо зарегистрировать его в Authy, чтобы включить 2FA:
@user = User.new(user_params) if @user.save session[:user_id] = @user.id authy = Authy::API.register_user( email: @user.email, cellphone: @user.phone_number, country_code: @user.country_code ) @user.update(authy_id: authy.id) redirect_to account_path else render :new end
Затем, когда пользователь пытается войти в систему, Вы можете использовать Authy для отправки токена через SMS, а затем проверить токен, который они введите:
def send_token @user = User.find(session[:pre_2fa_auth_user_id]) Authy::API.request_sms(id: @user.authy_id) render plain: 'sending token' end def verify @user = User.find(session[:pre_2fa_auth_user_id]) token = Authy::API.verify(id: @user.authy_id, token: params[:token]) if token.ok? session[:user_id] = @user.id session[:pre_2fa_auth_user_id] = nil redirect_to account_path else flash.now[:danger] = "Incorrect code, please try again" redirect_to new_session_path end end
Надеюсь, это поможет!
Кажется, что здесь лучше ответить самому себе: в конце концов, я обнаружил, что способ GitLab делать это 2FA больше всего соответствует моим потребностям: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/474
Поэтому я использую некоторые идеи из этого кода.
Спасибо вам, ребята из gitlab, вы мне очень помогли!