San*_*096 10 python django django-rest-framework
我知道这个主题已经被广泛讨论,但大多数示例都是关于标准 Django 模板中的两因素身份验证,而在我的例子中,我想向一个项目添加两因素身份验证,其中 Django 在后端用作 API,而前端是一个原生 VueJS 应用程序。
对于与身份验证相关的所有内容,我使用内置的 Django 会话身份验证,因为前端和后端都部署在同一服务器上。
我的问题是:如何将两因素身份验证(使用 google 身份验证器或 yubikey)添加到使用 django 作为 API 的项目中?
问题是/accounts/login:最简单的方法是让用户从前端登录,一旦用户从(内置的 django 身份验证视图)登录,就提交一个表单,用户必须在其中输入代码。这种方法的问题是,一旦用户登录,Django 将创建一个会话,因此即使用户尚未提交两因素代码request.user.is_authenticated也会返回True,因此一切都取决于前端。我不喜欢这种方法,因为我担心有人可能会找到一种方法来避免提交两因素表单并在网站的其余部分上导航(因为根据 Django,会话将被验证),而无需两因素身份验证
我尝试过的:我仍然需要为此编写大部分代码,因为我想首先了解它的安全性。但这是我的方法:
第一种方法
/authenticate。此端点将使用 Django 内置authenticate()方法来检查这些凭据是否属于用户,而无需创建会话。True给该用户。此时,用户将提交包含 2FA 代码的表单,如果代码正确,则会将请求发送到,该请求/accounts/login将再次检查密码和电子邮件,并实际登录用户并创建会话,这一次。第二种方法 另一种更好的方法是覆盖 Django-Allauth 登录视图,以便我可以添加对令牌的检查,例如(警告:伪代码):
if provided_code == user_code:
login()
return HttpResponse({'Result': 'Logged in!'})
else:
return HttpResponse({'Result': 'incorrect code'})
Run Code Online (Sandbox Code Playgroud)
provided_code用户提供的 2FA 代码在哪里?user_code我将从另一个函数(例如get_user_2fa_code(user).
我不是安全专家,但我没有想出更好的方法。会有多安全呢?有没有更好的方法将 2FA 身份验证添加到 Django 项目(其中 django 作为后端 API)?
class LoginView(
RedirectAuthenticatedUserMixin, AjaxCapableProcessFormViewMixin, FormView
):
form_class = LoginForm
template_name = "account/login." + app_settings.TEMPLATE_EXTENSION
success_url = None
redirect_field_name = "next"
@sensitive_post_parameters_m
def dispatch(self, request, *args, **kwargs):
return super(LoginView, self).dispatch(request, *args, **kwargs)
def get_form_kwargs(self):
kwargs = super(LoginView, self).get_form_kwargs()
kwargs["request"] = self.request
return kwargs
def get_form_class(self):
return get_form_class(app_settings.FORMS, "login", self.form_class)
def form_valid(self, form):
success_url = self.get_success_url()
try:
return form.login(self.request, redirect_url=success_url)
except ImmediateHttpResponse as e:
return e.response
def get_success_url(self):
# Explicitly passed ?next= URL takes precedence
ret = (
get_next_redirect_url(self.request, self.redirect_field_name)
or self.success_url
)
return ret
def get_context_data(self, **kwargs):
ret = super(LoginView, self).get_context_data(**kwargs)
signup_url = passthrough_next_redirect_url(
self.request, reverse("account_signup"), self.redirect_field_name
)
redirect_field_value = get_request_param(self.request, self.redirect_field_name)
site = get_current_site(self.request)
ret.update(
{
"signup_url": signup_url,
"site": site,
"redirect_field_name": self.redirect_field_name,
"redirect_field_value": redirect_field_value,
}
)
return ret
Run Code Online (Sandbox Code Playgroud)
这可能会有所帮助..我不确定。大多数现有的 django 2fa 项目都是按照你描述的方式工作的——我建议检查他们是如何做的以获得一些更好的提示。
django.contrib.auth.authenticate。此身份验证是凭据,但不会创建会话。django.contrib.auth.login对于登录身份验证视图和发布凭据 - 我做了这样的事情:
class TwoFactorAwareLoginView(TemplateView):
def post(self, request, *args, **kwargs):
form = self.form_class(data=request.POST, request=request)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(request, username=username, password=password)
if user is not None:
devices = <something to get your 2FA device blobs>
if not devices: #no user devices- log them in
login(request, user)
return HttpResponseRedirect(reverse("cool-page"))
else: #2FA devices exist- route them to verification view and perform auth_login once complete
# add some context needed for verification view in session or context
return HttpResponseRedirect(reverse("two-factor:verify-login"))
return render(request, self.template_name, {"form": form})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8599 次 |
| 最近记录: |