Django LDAP认证authenticate()调用报错,应使用何种实例?
问题:django-auth-ldap认证时出现
'WSGIRequest' object has no attribute 'settings'错误 我有一个基于LDAP的认证后端,代码如下:
class MyLDAPBackend(LDAPBackend): def authenticate(self, request, username=None, password=None, **kwargs): print("Try ldap auth") print(type(request)) # <class 'django.core.handlers.wsgi.WSGIRequest'> user = LDAPBackend.authenticate(request, username, password,kwargs)
运行时触发错误:
'WSGIRequest' object has no attribute 'settings'
查看django-auth-ldap库的源码后发现,父类的authenticate方法需要访问实例的settings属性:
class LDAPBackend: def authenticate(self, request, username=None, password=None, **kwargs): if username is None: return None if password or self.settings.PERMIT_EMPTY_PASSWORD: ldap_user = _LDAPUser(self, username=username.strip(), request=request) user = self.authenticate_ldap_user(ldap_user, password) else: logger.debug("Rejecting empty password for %s", username) user = None return user
框架传入的是WSGIRequest实例,请问该如何解决这个问题?
解决方案
错误的核心原因是调用父类实例方法时传参错误:你直接用LDAPBackend.authenticate(request, ...)调用时,把request传给了父方法的第一个参数self,但父方法里的self需要是LDAPBackend的实例,而非WSGIRequest对象,所以会触发settings属性不存在的错误。
修正后的代码有两种写法:
写法1:使用super()调用父类方法(推荐)
class MyLDAPBackend(LDAPBackend): def authenticate(self, request, username=None, password=None, **kwargs): print("Try ldap auth") print(type(request)) # <class 'django.core.handlers.wsgi.WSGIRequest'> # 用super()自动传递当前实例作为self参数 user = super().authenticate(request, username, password, **kwargs) return user
写法2:手动传入当前实例作为self参数
class MyLDAPBackend(LDAPBackend): def authenticate(self, request, username=None, password=None, **kwargs): print("Try ldap auth") print(type(request)) # <class 'django.core.handlers.wsgi.WSGIRequest'> # 显式传递self作为父方法的第一个参数 user = LDAPBackend.authenticate(self, request, username, password, **kwargs) return user
两种写法都能确保父类方法拿到正确的LDAPBackend实例,从而正常访问self.settings属性。
内容的提问来源于stack exchange,提问作者whitebear
相关产品推荐
相关产品推荐

