App Engine Jak utrzymać logowanie zarówno na http, jak i https za pomocą usługi Użytkownicy

Poniższy kod pokazuje problem, który mam, jest dostępny naGithub. Kiedy usuwam bezpieczną trasę do logowania, kod działa, ale gdy zabezpieczam stronę, nie działa. Lub jeśli ustawię stronę główną jako bezpieczną: zawsze / opcjonalnie. Ten kod nie zadziała na twoim serwerze dev, chyba że zmienisz schemat http w main.py z https na http.

Dlaczego ten kod nie działa z loginami przechodzącymi przez https?

app.yaml

application: testapp
version: 1
runtime: python27
api_version: 1
threadsafe: yes

libraries:
- name: webapp2
  version: latest

handlers:
- url: /login
  script: main.app
  secure: always

- url: /.*
  script: main.app
  secure: never

main.py

import webapp2
from google.appengine.ext.webapp import template
from google.appengine.api import users
from login import LoginHandler
from admin import AdminHandler

class HomeHandler(webapp2.RequestHandler):
    def get(self):
        user = users.get_current_user()
        if users.is_current_user_admin():
            loggedin = "Admin"
            values = {'loggedin': loggedin,
                      'logout_url': users.create_logout_url("/")}
        elif user:
            loggedin = "User"
            values = {'loggedin': loggedin,
                      'logout_url': users.create_logout_url("/")}
        else:
            loggedin = "Anonymous"
            values = {'loggedin': loggedin,
                      'logout_url': users.create_logout_url("/")}
        self.response.out.write(template.render('home.html', values))

app = webapp2.WSGIApplication([
    webapp2.Route(r'/', HomeHandler),
    webapp2.Route(r'/login', LoginHandler, schemes=['https']),
    webapp2.Route(r'/admin', AdminHandler, schemes=['https'])
], debug=True)

login.py

import webapp2
from google.appengine.ext.webapp import template
from google.appengine.api import users

#  Login page Request Handler Class
class LoginHandler(webapp2.RequestHandler):
    def get(self):
        user = users.get_current_user()

        values = {'login_url': users.create_login_url("/")}
        self.response.out.write(template.render('login.html', values))

admin.py

import webapp2
from google.appengine.ext.webapp import template
from google.appengine.api import users

#  Login page Request Handler Class
class AdminHandler(webapp2.RequestHandler):
    def get(self):
        user = users.get_current_user()

        values = {'user': users.nickname()}
        self.response.out.write(template.render('admin.html', values))

home.html

<html>
<body>
<p>Who is logged in: {{loggedin}}</p>
<ul>
  <li>
    {% ifequal loggedin "Anonymous" %}
      <a href="/login">Login</a>
    {% else %} <!-- user is logged in -->
      <a href="{{logout_url}}">Logout</a>
    {% endifequal %}
  </li>
  {% ifequal loggedin "Admin" %}
    <li class="right">
      <a href="/admin">Admin</a>
    </li>
  {% endifequal %}
</ul>
</body>
</html>

login.html

<html>
<body>
<ul>
  <li>
      <a href="{{login_url}}">Login</a>
  </li>
</ul>
</body>
</html>

admin.html

<html>
<body>
      <p>Your logged in as: {{user}}</p>
</body>
</html>

Jak widzisz bardzo prosty przykład, użytkownik klika link do logowania, przechodzi do strony logowania, na której loguje się przy użyciu uwierzytelniania Google i przekierowuje z powrotem na niezabezpieczoną stronę główną. Gdy użytkownik wraca do strony głównej, oczekiwane zachowanie polega na tym, że „Kto jest zalogowany” zwraca albo administratora / użytkownika / anonimowego, ale wszystko, co otrzymuję, jest anonimowe, adres URL wylogowania nie jest dodawany ani adres administracyjny administratora. Jeśli wykonam zwykły login http, to jeśli mam bezpieczną trasę do powiedzenia / admin, to żądanie otrzyma błąd 401.

Ten kod działa tylko wtedy, gdy robię wszystko, co jest HTTPS. Wiem, że inni korzystają z bezpiecznych stron logowania i nadal mają dostęp do informacji o użytkowniku na niezabezpieczonych stronach. Uważam, że ma to związek z tym, jak ustawiany jest plik cookie, ale nie mogę zrozumieć tego, co robię źle.

questionAnswers(1)

yourAnswerToTheQuestion