您可以使用django-mobile 库来检测来自移动浏览器的请求,然后调用不同的身份验证类。
django-mobile 库在其中定义了MobileDetectionMiddleware 和SetFlavourMiddleware 中间件类。
MobileDetectionMiddleware 检测请求是来自移动设备还是 Web 浏览器。
SetFlavourMiddleware 类在请求中设置flavour 属性。 flavour 有 2 个可能的值:
'mobile' # Mobile requests
'full' # Web requests
在中间件以某种方式选择了正确的风格之后,它被分配给request.flavour 属性。
第 1 步:在您的应用程序中配置 django-mobile
按照https://github.com/gregmuellegger/django-mobile#installation 中给出的步骤在您的应用程序中安装和配置django-mobile。
配置完成后,您可以使用request.flavour 来检查请求是来自移动浏览器还是网络浏览器。
第 2 步:创建自定义 WebSessionAuthentication 类
由于您想将 OAuth 的 OAuth2Authentication 用于移动应用程序,将 DRF 的 SessionAuthentication 用于 Web,我们可以创建一个自定义的 WebSessionAuthentication 类,该类将继承自 DRF 的 SessionAuthentication。
这个WebSessionAuthentication 类将不对移动请求执行任何身份验证。如果是 Web 请求,它将使用 CSRF 检查执行正确的会话身份验证。
from rest_framework.authentication import SessionAuthentication
class WebSessionAuthentication(SessionAuthentication):
"""
Performs session authentication for web requests
"""
def authenticate(self, request):
"""
Returns a `User` if the request session currently has a logged in user
and request is a web request
Otherwise returns `None`.
"""
underlying_request = request._request # get the underlying HttpRequest object
if underlying_request.flavour == 'mobile': # check if mobile request
return None # No authentication performed for mobile requests
# For web requests perform DRF's original session authentication
return super(WebSessionAuthentication, self).authenticate(request)
第 3 步:创建自定义 MobileOAuth2Authentication 类
MobileOAuth2Authentication 类仅对 mobile 请求执行身份验证,即具有 .flavour 为 mobile。不对web 请求执行身份验证。
from oauth2_provider.ext.rest_framework import OAuth2Authentication
class MobileOAuth2Authentication(OAuth2Authentication):
"""
Performs outh2 authentication for mobile requests
"""
def authenticate(self, request):
"""
Returns two-tuple of (user, token) if mobile authentication succeeds,
or None otherwise.
"""
underlying_request = request._request # get the underlying HttpRequest object
if underlying_request.flavour == 'full': # check if web request
return None # No authentication performed for web requests
# For mobile requests perform OAuth2's original authentication
return super(MobileOAuth2Authentication, self).authenticate(request)
第 4 步:在设置中定义您的身份验证类
创建自定义WebSessionAuthentication 和MobileOuth2Authentication 身份验证类后,在您的项目设置中定义这些身份验证类。
'DEFAULT_AUTHENTICATION_CLASSES': (
'my_app.authentication.WebSessionAuthentication', # custom session authentication class for web requests
'my_app.authentication.MobileOAuth2Authentication', # custom oauth2 authentication class for mobile requests
),