"TypeError: объект типа 'NoneType' не имеет len ()" после входа в пример кода Webapp2 Auth - PullRequest
2 голосов
/ 24 марта 2012

Я пытаюсь следовать примеру Auth для Webapp2, который можно найти здесь: http://code.google.com/p/webapp-improved/issues/detail?id=20

Фактически main.py это:

# -*- coding: utf-8 -*-

import webapp2
from webapp2_extras import auth
from webapp2_extras import sessions
from webapp2_extras.auth import InvalidAuthIdError
from webapp2_extras.auth import InvalidPasswordError

def user_required(handler):
    """
         Decorator for checking if there's a user associated with the current session.
         Will also fail if there's no session present.
     """

    def check_login(self, *args, **kwargs):
        auth = self.auth
        if not auth.get_user_by_session():
            # If handler has no login_url specified invoke a 403 error
            try:
                self.redirect(self.auth_config['login_url'], abort=True)
            except (AttributeError, KeyError), e:
                self.abort(403)
        else:
            return handler(self, *args, **kwargs)

    return check_login


class BaseHandler(webapp2.RequestHandler):
    """
         BaseHandler for all requests

         Holds the auth and session properties so they are reachable for all requests
     """

    def dispatch(self):
        """
              Save the sessions for preservation across requests
          """
        try:
            response = super(BaseHandler, self).dispatch()
            self.response.write(response)
        finally:
            self.session_store.save_sessions(self.response)

    @webapp2.cached_property
    def auth(self):
        return auth.get_auth()

    @webapp2.cached_property
    def session_store(self):
        return sessions.get_store(request=self.request)

    @webapp2.cached_property
    def auth_config(self):
        """
              Dict to hold urls for login/logout
          """
        return {
            'login_url': self.uri_for('login'),
            'logout_url': self.uri_for('logout')
        }


class LoginHandler(BaseHandler):
    def get(self):
        """
              Returns a simple HTML form for login
          """
        return """
            <!DOCTYPE hml>
            <html>
                <head>
                    <title>webapp2 auth example</title>
                </head>
                <body>
                <form action="%s" method="post">
                    <fieldset>
                        <legend>Login form</legend>
                        <label>Username <input type="text" name="username" placeholder="Your username" /></label>
                        <label>Password <input type="password" name="password" placeholder="Your password" /></label>
                    </fieldset>
                    <button>Login</button>
                </form>
            </html>
        """ % self.request.url

    def post(self):
        """
              username: Get the username from POST dict
              password: Get the password from POST dict
          """
        username = self.request.POST.get('username')
        password = self.request.POST.get('password')
        # Try to login user with password
        # Raises InvalidAuthIdError if user is not found
        # Raises InvalidPasswordError if provided password doesn't match with specified user
        try:
            self.auth.get_user_by_password(username, password)
            self.redirect('/secure/')
            #self.response.out.write('Hello, webapp World!')
        except (InvalidAuthIdError, InvalidPasswordError), e:
            # Returns error message to self.response.write in the BaseHandler.dispatcher
            # Currently no message is attached to the exceptions

            e = "shit"

            return e


class CreateUserHandler(BaseHandler):
    def get(self):
        """
              Returns a simple HTML form for create a new user
          """
        return """
            <!DOCTYPE hml>
            <html>
                <head>
                    <title>webapp2 auth example</title>
                </head>
                <body>
                <form action="%s" method="post">
                    <fieldset>
                        <legend>Create user form</legend>
                        <label>Username <input type="text" name="username" placeholder="Your username" /></label>
                        <label>Password <input type="password" name="password" placeholder="Your password" /></label>
                    </fieldset>
                    <button>Create user</button>
                </form>
            </html>
        """ % self.request.url

    def post(self):
        """
              username: Get the username from POST dict
              password: Get the password from POST dict
          """
        username = self.request.POST.get('username')
        password = self.request.POST.get('password')
        # Passing password_raw=password so password will be hashed
        # Returns a tuple, where first value is BOOL. If True ok, If False no new user is created
        user = self.auth.store.user_model.create_user(username, password_raw=password)
        if not user[0]: #user is a tuple
            return user[1] # Error message
        else:
            # User is created, let's try redirecting to login page
            try:
                self.redirect(self.auth_config['login_url'], abort=True)
            except (AttributeError, KeyError), e:
                self.abort(403)


class LogoutHandler(BaseHandler):
    """
         Destroy user session and redirect to login
     """

    def get(self):
        self.auth.unset_session()
        # User is logged out, let's try redirecting to login page
        try:
            self.redirect(self.auth_config['login_url'])
        except (AttributeError, KeyError), e:
            return "User is logged out"


class SecureRequestHandler(BaseHandler):
    """
         Only accessible to users that are logged in
     """

    @user_required
    def get(self, **kwargs):
        user = self.auth.get_user_by_session()
        try:
            return "Secure zone for %s <a href='%s'>Logout</a>" % (str(user), self.auth_config['logout_url'])
        except (AttributeError, KeyError), e:
            return "Secure zone"


class MainPage(webapp2.RequestHandler):
  def get(self):
      #self.response.headers['Content-Type'] = 'text/plain'
      self.response.out.write('Hello, webapp World!')


webapp2_config = {}
webapp2_config['webapp2_extras.sessions'] = {
        'secret_key': 'Im_an_alien',
    }

app = webapp2.WSGIApplication([
        webapp2.Route(r'/login/', handler=LoginHandler, name='login'),
        webapp2.Route(r'/logout/', handler=LogoutHandler, name='logout'),
        webapp2.Route(r'/secure/', handler=SecureRequestHandler, name='secure'),
        webapp2.Route(r'/create/', handler=CreateUserHandler, name='create-user')

    ], debug=True)

Когда я создаю пользователя и пытаюсь войти в него, я получаю следующую трассировку:

object of type 'NoneType' has no len()
Traceback (most recent call last):
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1511, in __call__
    rv = self.handle_exception(request, response, e)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1505, in __call__
    rv = self.router.dispatch(request, response)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1253, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2.py", line 1077, in __call__
    return handler.dispatch()
  File "/base/data/home/apps/s~deafphoneconnect/1.357704879430861291/main.py", line 44, in dispatch
    self.session_store.save_sessions(self.response)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2_extras/sessions.py", line 420, in save_sessions
    session.save_session(response)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2_extras/sessions.py", line 205, in save_session
    response, self.name, dict(self.session), **self.session_args)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2_extras/sessions.py", line 423, in save_secure_cookie
    value = self.serializer.serialize(name, value)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2_extras/securecookie.py", line 47, in serialize
    signature = self._get_signature(name, value, timestamp)
  File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2_extras/securecookie.py", line 98, in _get_signature
    signature = hmac.new(self.secret_key, digestmod=hashlib.sha1)
  File "/base/python27_runtime/python27_dist/lib/python2.7/hmac.py", line 133, in new
    return HMAC(key, msg, digestmod)
  File "/base/python27_runtime/python27_dist/lib/python2.7/hmac.py", line 68, in __init__
    if len(key) > blocksize:
TypeError: object of type 'NoneType' has no len()

Я знаю, что это не мой SDK, потому что это также происходит при развертывании приложения, однако мне пришлось вручную добавить ndb в проект.

Есть идеи о том, что здесь происходит?

1 Ответ

3 голосов
/ 24 марта 2012

Вы не передаете параметр config = webapp2_config в вызов WSGIApplication.Я сравнил это со ссылкой здесь.

http://webapp -improved.appspot.com / guide / extras.html

...