如果 user/device 在过去 30 天内登录,希望 django-two-factor-auth 跳过令牌步骤

Want to have django-two-factor-auth skip token step if user/device logged in during the last 30 days

首先,如果有人做过,请指教:)

现在,我正在考虑继承 LoginView 方法 get_context_data()(来自 django-two-factor-auth包)。

新方法的第一行是:

if  self.steps.current == 'token':
    (pseudo code)
    if user_agent == current user_agent and last_activity < 30 days ago (from table user_sessions_session):
       return context # skip the token step

我看到这是一个 desired feature 但尚未实施

我用更改 here and put in a pull request. You can review the changes here 分叉了存储库(更改的覆盖率为 100%)。

基本上,如果有有效的登录(使用令牌),它会设置一个仅限于登录页面的签名 cookie。之后的登录将检查该签名的 cookie,如果它存在且未过期,它将允许在没有令牌的情况下登录。这是关键逻辑:

def token_required(self, request):
    """
    if this user logged with a token in the last {{TWO_FACTOR_TRUSTED_DAYS}}
    days, they can skip the token steps.
    """
    end_valid_login = None
    if not request.COOKIES.get('evl'):
        return True
    try:
        end_valid_login = request.get_signed_cookie('evl',
                salt=settings.TWO_FACTOR_SALT)
    except (BadSignature, SignatureExpired) as e:
        return True
    end_valid_login_dt = datetime.strptime(end_valid_login, '%Y-%m-%d')
    if datetime.today() < end_valid_login_dt:
        #--- the cookie is valid and still within {{TWO_FACTOR_TRUSTED_DAYS}} ---#
        return False
    else:
        return True

注意:(2020 年 3 月编辑)

实际上,我建议任何实施 2FA 的人都使用 Webauthn. I think it makes all other methods obsolete and will become the standard everywhere. Here is an explanation of the inherent weaknesses of other 2FA methods