Django为WebView返回一个带有TokenAuthentication的视图



我正在尝试创建一个flutter应用程序,该应用程序将使用webview来显示我的Django应用程序中经过验证的数据。

涉及步骤:

  1. Flutter应用程序发送身份验证请求
  2. Django验证用户凭据(用户id和密码(并返回authtoken
  3. Flutter随后通过网络视图向url发送请求(需要登录(

我想使用此令牌登录webapp中的用户并返回webview。如果url不需要身份验证,它就像一个符咒。当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);
},
),      
);
}
}

这可能吗?如果有其他方法,请告诉我。基本上,我试图通过webview访问url,这需要使用authtoken进行身份验证。请帮忙。

您可以像这样使用自定义身份验证类,比如说,如果您使用的是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, )

您可以使用来自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

或者浏览以下链接以更好地理解【代币授权】

最新更新