注销后Django重新加载并重新登录

时间:2015-11-06 22:15:53

标签: python django persona

Django v1.7

我一直在研究this book(这太棒了,顺便说一句),我以为我的一切都在运转。所有测试(功能和单位),但由于某种原因,每次我点击logout按钮,我立即重新登录。我正在使用自定义身份验证后端(书中给出的)它使用了Mozilla Persona,如书中所述(链接中的章节)。

我看过一些类似的帖子,但没有一个解决方案有帮助。

行为:

  1. 使用错误的凭据登录将不断刷新页面, 似乎每次都会查询Persona(Persona错误: Persona says no. Json was: {'status': 'failure', 'reason': 'audience mismatch: domain mismatch'} - 我意外地发现了 访问127.0.0.1:8000而不是localhost:8000 *)。一世 不知道每次是否询问人物角色,或者是否有消息 在每次刷新页面后保留。
  2. 初始登录似乎正常。在关闭并重新加载页面之前,会出现角色弹出窗口并执行这些步骤。

  3. 注销后,页面将刷新,发送帖子信息并重新登录: [06/Nov/2015 21:25:20] "GET /accounts/logout HTTP/1.1" 302 0 [06/Nov/2015 21:25:20] "GET / HTTP/1.1" 200 795 [06/Nov/2015 21:25:21] "POST /accounts/login HTTP/1.1" 200 2 注销被重定向回根页面“/”。

  4. 通过重新启动服务器和Web浏览器,此行为是持久的。如果我停止服务器并关闭浏览器并重新打开(再次输入网址),则该页面已经登录。

  5. 此行为也会通过不同的git分支持续存在。我不确定它何时开始(因为测试仍然通过),但我知道它之前有用。我检查的每个分支都有相同的问题,这让我觉得它与缓存或安装有关。

  6. 通过删除所有__pycache__,迁移和数据库本身,行为也会持续存在。

  7. 通过清除缓存,此行为仍然存在。 (编辑/更新:我还在写这个,所以从技术上来说这不是更新......我以前只为“今天”(Firefox)清空缓存,这没有效果;但是,我刚刚清除了所有内容,似乎已经解决了问题。我需要做更多测试;一旦我确定,我会更新。)

  8. *我确实知道Persona说使用ip而不是localhost,但它似乎没有什么区别。

    这是一个最小的工作示例:

    placeholder.html(注意:我将脚本放在正文中。

    {% load staticfiles %}
    
    <html>
    <head>
        <title>placeholder</title>
    </head>
    
    <body>
        {% if user.email %}
            <h3>User: {{ user.email }}</h3>
            <div class="item">
                Logged in as <b>{{ user.email }}</b>
            </div>
            <div class="item">
                <a class="ui button" id="id_logout"
                    href="{% url 'logout' %}">Log out</a>
            </div>
        {% else %}
            <div class="item">
                <a class="ui button" id="id_login" href="#">Sign in</a>
            </div>
        {% endif %}
    
        <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
        <script src="https://login.persona.org/include.js"></script>
    
        <script>
        var initialize = function(navigator, user, token, urls) {
          console.log('called initialize');
          $('#id_login').on('click', function() {
            navigator.id.request();
          });
          navigator.id.watch({
            loggedInUser: user,
            onlogin: function(assertion) {
              $.post(
                urls.login,
                {'assertion': assertion, 'csrfmiddlewaretoken': token}
              )
                .done(function() { window.location.reload(); })
                .fail(function() { navigator.id.logout(); });
            },
            onlogout: function() {}
          });
        };
    
        window.MyModule = window.MyModule || {
          Accounts: {
            initialize: initialize
          }
        };
        </script>
    
        <script>
        /*global $, MyModule, navigator */
        $(document).ready(function () {
            var user = "{{ user.email }}" || null;
            var token = "{{ csrf_token }}";
            var urls = {
                login: "{% url 'persona_login' %}",
                logout: "TODO",
            };
            MyModule.Accounts.initialize(navigator, user, token, urls);
        });
    </script>
    
    </body>
    </html>
    

    accounts / views.py(注意:我使用的是Django native auth.logout,你会在urls.py中看到)

    from django.contrib.auth import authenticate, login
    from django.contrib.auth import logout as auth_logout
    from django.http import HttpResponse
    from django.shortcuts import redirect
    
    def persona_login(request):
        user = authenticate(assertion=request.POST['assertion'])
        if user is not None:
            login(request, user)
        return HttpResponse('OK')
    
    
    def logout(request, next_page):
        auth_logout(request)
        return redirect('/')
    

    urls.py

    from django.conf.urls import patterns, include, url
    #from django.contrib import admin
    
    urlpatterns = patterns(
        '',
        # url(r'^admin/', include(admin.site.urls)),
    
        url(r'^accounts/', include('apps.accounts.urls')),
    
        url(r'^$', 'apps.projects.views.placeholder_view',
            name='placeholder'),
    )
    

    accounts / urls.py(注意:我使用的是本机注销 - 两种方法都不起作用)

    from django.conf.urls import patterns, url
    # from django.contrib.auth.views import logout
    
    urlpatterns = patterns(
        '',
        url(r'^login$', 'remsci.apps.accounts.views.persona_login',
            name='persona_login'),
        # url(r'^logout$', logout,
        #     {'next_page': '/'}, name='logout'),
        url(r'^logout$', 'remsci.apps.accounts.views.logout',
            {'next_page': '/'}, name='logout'),
    

    authentication.py(注意:这直接来自本书)

    import requests
    
    from django.conf import settings
    from django.contrib.auth import get_user_model
    
    User = get_user_model()
    
    PERSONA_VERIFY_URL = 'https://verifier.login.persona.org/verify'
    
    import logging
    log = logging.getLogger(__name__)
    
    class PersonaAuthenticationBackend(object):
    
        def authenticate(self, assertion):
            response = requests.post(
                PERSONA_VERIFY_URL,
                data={'assertion': assertion, 'audience': settings.DOMAIN}
            )
    
            if response.ok and response.json()['status'] == 'okay':
                email = response.json()['email']
                try:
                    return User.objects.get(email=email)
                except User.DoesNotExist:
                    return User.objects.create(email=email)
            else:
                log.warning(
                    'Persona says no. Json was: {}'.format(response.json()))
    
        def get_user(self, email):
            try:
                return User.objects.get(email=email)
            except User.DoesNotExist:
                return None
    

    编辑/更新再次,当我写这篇文章时。看来这个问题已经解决了here。我有一本书的实际副本,但是通过在线拷贝返回并验证所有内容,我刚刚找到指向此代码的链接。我会把它留下来,以防其他人遇到这个问题...或者,如果我能找到指向相同解决方案的同样问题,我会删除它。

1 个答案:

答案 0 :(得分:1)

从上面:

It would appear that this problem has already been solved here。我有一本书的实际副本,但是通过在线拷贝返回并验证所有内容,我刚刚找到指向此代码的链接。我会把它留下来,以防其他人遇到这个问题......或者,如果我能找到指向同一解决方案的同样问题,我会删除它。

相关问题