【问题标题】:Missing needed parameter state Python social auth Email Validation缺少所需的参数状态 Python 社交身份验证电子邮件验证
【发布时间】:2015-10-28 03:11:09
【问题描述】:

我正在将 python 社交身份验证与 django 应用程序一起使用。在电子邮件验证中,邮件中收到的链接在启动身份验证的同一浏览器中工作正常,但在不同的浏览器中显示Missing needed parameter state。有人解决了这个问题吗?

这里讨论了这个问题Issue #577

【问题讨论】:

    标签: python django python-social-auth


    【解决方案1】:

    这是因为其他浏览器没有部分管道数据!

    Christopher Keefer 通过获取 Django 会话表的 session_key 来处理 monkey-patch。对此还有一篇博文here,参考本文第三步。

    # Monkey patching - an occasionally necessary evil.
    from social import utils
    from social.exceptions import InvalidEmail
    
    from django.core import signing
    from django.core.signing import BadSignature
    from django.contrib.sessions.models import Session
    from django.conf import settings
    
    
    def partial_pipeline_data(backend, user=None, *args, **kwargs):
        """
        Monkey-patch utils.partial_pipeline_data to enable us to retrieve session data by signature key in request.
        This is necessary to allow users to follow a link in an email to validate their account from a different
        browser than the one they were using to sign up for the account, or after they've closed/re-opened said
        browser and potentially flushed their cookies. By adding the session key to a signed base64 encoded signature
        on the email request, we can retrieve the necessary details from our Django session table.
        We fetch only the needed details to complete the pipeline authorization process from the session, to prevent
        nefarious use.
        """
        data = backend.strategy.request_data()
        if 'signature' in data:
            try:
                signed_details = signing.loads(data['signature'], key=settings.EMAIL_SECRET_KEY)
                session = Session.objects.get(pk=signed_details['session_key'])
            except BadSignature, Session.DoesNotExist:
                raise InvalidEmail(backend)
    
            session_details = session.get_decoded()
            backend.strategy.session_set('email_validation_address', session_details['email_validation_address'])
            backend.strategy.session_set('next', session_details.get('next'))
            backend.strategy.session_set('partial_pipeline', session_details['partial_pipeline'])
            backend.strategy.session_set(backend.name + '_state', session_details.get(backend.name + '_state'))
            backend.strategy.session_set(backend.name + 'unauthorized_token_name',
                                         session_details.get(backend.name + 'unauthorized_token_name'))
    
        partial = backend.strategy.session_get('partial_pipeline', None)
        if partial:
            idx, backend_name, xargs, xkwargs = \
                backend.strategy.partial_from_session(partial)
            if backend_name == backend.name:
                kwargs.setdefault('pipeline_index', idx)
                if user:  # don't update user if it's None
                    kwargs.setdefault('user', user)
                kwargs.setdefault('request', backend.strategy.request_data())
                xkwargs.update(kwargs)
                return xargs, xkwargs
            else:
                backend.strategy.clean_partial_pipeline()
    utils.partial_pipeline_data = partial_pipeline_data
    

    这在很大程度上解决了问题,但仍然不完美。如果 session_key 在数据库中被删除/更改,它将失败。每次会话数据更改时,Django 都会更新 session_key。因此,如果任何其他用户在同一浏览器中登录,则 session_key 会发生更改,并且用户无法使用电子邮件链接进行验证。

    Omab在issue的评论中提到过,

    我现在看到了问题,即使我认为可以通过重新编写电子邮件验证管道来解决这个问题,但这会影响使用部分机制的所有管道功能,所以,我已经在努力了管道序列化功能的重组将改善此行为。基本上管道数据将被转储到数据库表中,并且将使用哈希码来识别可以停止并稍后继续的进程,从而消除会话的依赖性。

    寻找这方面的更新。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-02
      • 2015-08-18
      • 2021-04-18
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多