简体   繁体   English

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

[英]Django reload and re-login after logout

Django v1.7 Django v1.7

I've been working through this book (which is fantastic, btw), and I thought I had everything working. 我一直在研究这本书 (顺便说一句,太棒了),我认为我已经做好了一切。 All of the tests (functional and unit), but for some reason, every time I hit the logout button, I am immediately logged back in. I am using a custom authentication backend (the one given in the book), which uses Mozilla Persona, as described in the book (the chapter in the link). 所有测试(功能和单元),但是由于某种原因,每当我按下logout按钮时,我都会立即重新登录。我使用的是自定义身份验证后端(书中给出的一个),该后端使用Mozilla Persona ,如书中所述(链接中的章节)。

I have seen a few similar posts, but none of the solutions helped. 我看到过一些类似的帖子,但是没有一个解决方案有帮助。

Behaviour: 行为:

  1. Logging in with bad credentials will continually refresh the page, which appears to query Persona each time (the Persona error: Persona says no. Json was: {'status': 'failure', 'reason': 'audience mismatch: domain mismatch'} --I accidentally discovered this by visiting 127.0.0.1:8000 instead of localhost:8000 *). 使用错误的凭据登录将不断刷新页面,该页面似乎每次都会查询Persona(Persona错误: Persona says no. Json was: {'status': 'failure', 'reason': 'audience mismatch: domain mismatch'} -我通过访问127.0.0.1:8000而不是localhost:8000 *偶然发现了这一点。 I do not know if Persona is queried each time or if the message is kept after each page refresh. 我不知道是否每次都查询Persona或是否在每次刷新页面后保留该消息。
  2. The initial login appears to work correctly. 初始登录似乎正常工作。 The persona pop-up appears and goes through the steps before closing and reloading the page. 在关闭并重新加载页面之前,将显示“角色”弹出窗口,并执行相应的步骤。

  3. After logging out, the page will refresh, sending post information and logging back in: [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 The logout is redirected back to the root page '/'. 注销后,页面将刷新,发送帖子信息并重新登录: [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. This behaviour is persistent through restarting the server and the web browser. 通过重新启动服务器和Web浏览器,此行为将持续存在。 If I stop the server and close the browser and reopen both (entering in the web address again), the page is already logged in. 如果我停止服务器并关闭浏览器并重新打开两者(再次输入网址),则该页面已登录。

  5. This behaviour also persists through different git branches. 此行为也通过不同的git分支持续存在。 I am not sure when it started (because the tests still pass), but I know it worked previously. 我不确定它什么时候开始(因为测试仍然可以通过),但是我知道它以前可以工作。 Every branch I checked has the same issue, which makes me think it's something to do with the cache or installation. 我检查的每个分支都有相同的问题,这使我认为这与缓存或安装有关。

  6. The behaviour also persists through removing all __pycache__, migrations, and the database itself. 通过删除所有__pycache__,迁移和数据库本身,该行为也将持续存在。

  7. The behaviour persists through clearing the cache. 通过清除缓存,该行为仍然存在。 ( EDIT/UPDATE : I'm still writing this, so it's not technically an update...I had previously emptied the cache only for 'Today' (Firefox), which had no effect; however, I just cleared everything, and it seems to have solved the problem. I need to do more testing; I'll update once I'm sure.) 编辑/更新 :我仍然在写这篇文章,所以从技术上讲它不是更新...我以前只清空了'Today'(Firefox)的缓存,这没有效果;但是,我只是清除了所有内容,似乎已经解决了这个问题。我需要做更多的测试;确定后我会进行更新。)

*I do know that Persona says to use the ip over localhost , but it doesn't seem to make a difference. *我确实知道Persona说要在localhost上使用ip,但是似乎没有什么不同。

Here's a minimal working example: 这是一个最小的工作示例:

placeholder.html (NOTE: I put the scripts in the body. 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 (NOTE: I was using Django native auth.logout, which you will see in urls.py) accounts / views.py(注意:我使用的是Django本机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 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 (NOTE: I was using the native logout--neither method works) account / 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 (NOTE: This is directly from the book) 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

EDIT/UPDATE Again, while I was writing this. 编辑/更新,再次,当我写这个。 It would appear that this problem has already been solved here . 看来这个问题已经在这里解决 I have a physical copy of the book, but going back through and verifying everything using the online copy, I just found the link pointing to this code. 我有这本书的物理副本,但是使用在线副本回顾并验证所有内容,我只是找到指向此代码的链接。 I'll leave this up, just in case someone else is having this problem...or, I'll remove it if I can find the same problem pointing to the same solution. 如果有人遇到这个问题,我将不予理会...或者,如果我发现指向相同解决方案的相同问题,则将其删除。

From above: 从上面:

It would appear that this problem has already been solved here . 看来这个问题已经在这里解决了 I have a physical copy of the book, but going back through and verifying everything using the online copy, I just found the link pointing to this code. 我有这本书的物理副本,但是使用在线副本回顾并验证所有内容,我只是找到指向此代码的链接。 I'll leave this up, just in case someone else is having this problem...or, I'll remove it if I can find the same problem pointing to the same solution. 如果有人遇到这个问题,我将不予理会...或者,如果我发现指向相同解决方案的相同问题,则将其删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM