Django 为 WebView 返回一个带有 TokenAuthentication 的视图
Posted
技术标签:
【中文标题】Django 为 WebView 返回一个带有 TokenAuthentication 的视图【英文标题】:Django to return a view with TokenAuthentication for WebView 【发布时间】:2021-09-14 12:12:06 【问题描述】:我正在尝试创建一个颤振应用程序,它将使用 webview 显示来自我的 Django 应用程序的经过身份验证的数据。
涉及的步骤:
-
Flutter 应用发送身份验证请求
Django 验证用户凭据(用户 ID 和密码)并返回 authtoken
Flutter 然后通过 webview 向 url 发送请求(需要登录)。
我想使用此令牌在 webapp 中登录用户并返回 webview。 如果 url 不需要 authentcation,它就像一个魅力。 当 url 需要身份验证时,我被重定向到登录页面,我希望用户使用步骤 1 中已获取的令牌身份验证绕过该页面
这是我的 Django 视图。
class QuizTake(FormView):
permission_classes = (IsAuthenticated,)
form_class = QuestionForm
template_name = 'question.html'
result_template_name = 'result.html'
single_complete_template_name = 'single_complete.html'
login_template_name='login.html'
def dispatch(self, request, *args, **kwargs):
self.quiz = get_object_or_404(Quiz, url=self.kwargs['quiz_name'])
print(self.kwargs['quiz_name'])
"""
Authenticate if the request has token authentication
"""
if self.quiz.draft and not request.user.has_perm('quiz.change_quiz'):
raise PermissionDenied
try:
self.logged_in_user = self.request.user.is_authenticated()
except TypeError:
self.logged_in_user = self.request.user.is_authenticated
if self.logged_in_user:
self.sitting = Sitting.objects.user_sitting(request.user,
self.quiz)
else:
self.sitting = self.anon_load_sitting()
if self.sitting is False:
print("sitting false")
if self.logged_in_user:
return render(request, self.single_complete_template_name)
else:
redirecturl = "/login/?next=/quiz/"+self.kwargs['quiz_name']+"/take/"
return redirect(redirecturl)
return super(QuizTake, self).dispatch(request, *args, **kwargs)
颤动代码
class _QuizLauncherState extends State<QuizLauncher>
final String url, authtoken;
final int userId;
String quizUrl;
_QuizLauncherState(this.url, this.authtoken,this.userId);
void initState()
quizUrl = 'https://test.mysite.com/quiz/$url/take';
print(quizUrl);
//for reference https://test.mysite.com/quiz/56df5d90-7f67-45ff-8fe1-7c07728ba9ab/take/
super.initState();
Completer<WebViewController> _controller = Completer<WebViewController>();
final Set<String> _favorites = Set<String>();
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
// This drop down menu demonstrates that Flutter widgets can be shown over the web view.
actions: <Widget>[
NavigationControls(_controller.future),
Menu(_controller.future, () => _favorites),
],
),
body: WebView(
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController)
Map<String, String> headers = "Authorization": "Bearer " + authtoken;
webViewController.loadUrl(quizUrl, headers: headers);
,
),
);
这可能吗?如果有任何替代方法,请告诉我。基本上,我正在尝试使用 authtoken 通过需要身份验证的 webview 访问 url。请帮忙。
【问题讨论】:
您是否尝试过创建一个身份验证类来处理您的令牌? 如何使用 url 从颤振中传递令牌,这实际上会传递 authtoken 吗?onWebViewCreated: (WebViewController webViewController) Maprequest.META.get('HTTP_AUTHORIZATION')
从请求中提取授权标头值
【参考方案1】:
您可以像这样使用自定义身份验证类,例如,如果您使用的是 Authorization 标头:
from rest_framework.authentication import BaseAuthentication
class MyCustomAuth(BaseAuthentication):
def authenticate(self, request):
auth_method, token = request.META['HTTP_AUTHORIZATION'].split(' ', 1)
# Get your user via the token here
if you_got_your_user:
return user, None
return None # or raise AuthFailedException
class QuizTake(FormView):
authentication_classes = (MyCustomAuth, )
这仍然取决于您的令牌如何识别用户。例如,如果您使用的是 JWT,那么已经有现有的身份验证类可以为您处理这个问题。
编辑:
查看来自here
的 knox 文档。如果你使用了knox,那么你大概应该使用自己的TokenAuthentication
类。你可以试试下面的代码:
from knox.auth import TokenAuthentication
class QuizTake(FormView):
authentication_classes = (TokenAuthentication, )
【讨论】:
我对迟到的回复表示歉意。您能否详细说明#Get your user via the token here 以及如何对其进行身份验证。我正在使用 Knox 身份验证。请一点帮助 看来诺克斯有自己的TokenAuthentication
。你可以试试看它是否适合你的观点?
非常感谢。身份验证问题已解决。但是,我记录了另一个让我感到困惑的查询***.com/questions/68431241/… 任何帮助表示赞赏。【参考方案2】:
您可以使用来自 rest 框架库的身份验证,如下代码所示。
import base64
import binascii
from django.contrib.auth import authenticate, get_user_model
from django.middleware.csrf import CsrfViewMiddleware
from django.utils.translation import gettext_lazy as _
from rest_framework import HTTP_HEADER_ENCODING, exceptions
def get_authorization_header(request):
auth = request.META.get('HTTP_AUTHORIZATION', b'')
if isinstance(auth, str):
auth = auth.encode(HTTP_HEADER_ENCODING)
return auth
class BaseAuthentication:
raise NotImplementedError(".authenticate() must be overridden.")
def authenticate_header(self, request):
pass
class SessionAuthentication(BaseAuthentication):
user = getattr(request._request, 'user', None)
if not user or not user.is_active:
return None
self.enforce_csrf(request)
return (user, None)
def enforce_csrf(self, request):
def dummy_get_response(request):
return None
check = CSRFCheck(dummy_get_response)
check.process_request(request)
reason = check.process_view(request, None, (), )
if reason:
raise exceptions.PermissionDenied('CSRF Failed: %s' % reason)
class TokenAuthentication(BaseAuthentication):
keyword = 'Token'
model = None
def get_model(self):
if self.model is not None:
return self.model
from rest_framework.authtoken.models import Token
return Token
或通过以下链接更好地理解 [令牌授权]
【讨论】:
您好,您的回答似乎是基于我的。你能详细说明它有多大不同吗?如果没有,请看这里:***.com/help/referencing @bdbd 我已经更改了我的代码,您可以在上面检查并删除标志以上是关于Django 为 WebView 返回一个带有 TokenAuthentication 的视图的主要内容,如果未能解决你的问题,请参考以下文章
带有两个提交按钮的 Django 表单。 . .一个需要字段,一个不需要
无法使用带有 Django 的 MongoEngine Pymongo 返回 JSON 对象?
django-allauth 为带有参数“()”和关键字参数“”的“account_confirm_email”返回错误反向
尝试退出插件 webview 时,带有集成插件的 Cordova 应用程序在 webview 上崩溃(android 测试)