2

次のコードは、私が抱えている問題を示しています。Githubで入手できます。ログイン用の安全なルートを削除するとコードは機能しますが、ページを保護すると機能しません。または、ホームページを安全にする場合:常に/オプション。このコードは、main.py の http スキームを https から http に変更しない限り、開発サーバーでは機能しません。

このコードが 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>

非常に単純な例を見るとわかるように、ユーザーはログイン リンクをクリックし、Google 認証でログインするログイン ページに移動し、保護されていないホームページにリダイレクトされます。ユーザーがホームページに戻ると、「ログインしているユーザー」が admin/user/anonymous のいずれかを返しますが、得られるのはすべて匿名であり、ログアウト URL が追加されないか、管理者ユーザーの管理 URL です。ログインを通常の http にすると、/admin と言う安全なルートがあれば、そのリクエストは 401 エラーを受け取ります。

このコードは、すべてを HTTPS にした場合にのみ機能します。他のユーザーが安全なログイン ページを使用していても、安全でないページのユーザー情報にアクセスできることは知っています。これはCookieの設定方法に関係していると思いますが、何が間違っているのか途方に暮れています。

4

1 に答える 1

0

FireCookie (または同様のもの) で Cookie の詳細を確認しましたか? パス、ドメインなどは? 安全のために別のドメイン名を使用していますか? https の場合は secure.app.com、http の場合は www.app.com のように?

私は GAE で https を試したことはありません。

于 2012-07-16T17:12:37.967 に答える