Como manter o login no http e no https com o serviço de usuários
O código a seguir demonstra o problema que tenho, está disponível emGithub. Quando eu removo a rota segura para o login, o código funciona, mas quando eu seguro a página não funciona. Ou se eu tornar a página inicial segura: sempre / opcional. Este código não funcionará no seu servidor de desenvolvimento, a menos que você altere o esquema http em main.py de https para http.
Por que esse código não funciona com logins passando por 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>
Como você pode ver um exemplo muito simples, o usuário clica no link de login, acessa a página de login na qual ele faz login com o Google Authentication e é redirecionado de volta para a página inicial não segura. Quando o usuário retorna à página inicial, o comportamento esperado é que "Quem está logado" retorna admin / user / anonymous, mas tudo que recebo é anônimo, a URL de logout não é adicionada ou a URL de administração de um usuário administrador. Se eu fizer o logon http normal, então, se eu tiver uma rota segura para dizer / admin que a solicitação recebe um erro 401.
Esse código só funciona quando eu faço fazer tudo HTTPS. Eu sei que outras pessoas estão usando páginas de login seguras e ainda conseguem acessar as informações do usuário em páginas não seguras. Eu acredito que isso tem a ver com a forma como o cookie está sendo definido, mas eu estou em uma perda em que estou fazendo errado.