Обработка сеансов в Google App Engine с помощью Android/IPhone

Я начинаю писать приложение, в соответствии с которым мобильное приложение (Android/IPhone) будет связываться с бэкэндом GAE (Python) с помощью серии вызовов веб-API с использованием JSON.

Я не могу использовать учетные записи Google для аутентификации, поэтому мне нужно реализовать свой собственный auth. У меня есть идея, как это сделать, но я не уверен, есть ли лучший способ.

Может ли кто-нибудь помочь с некоторыми примерами кода/предложениями о том, как достичь ниже, пожалуйста?

Метод

  • Мобильное приложение вызывает метод Login на сервере, который проверяет подлинность и создает ключ сеанса в хранилище и возвращает это в приложение - не уверен, как сгенерировать ключ/сеанс или где на запрос/ответ он должен быть.
  • При каждом вызове приложение передает этот ключ для аутентификации сервера и разрешает действие, если оно проходит.
  • Пользователю не нужно снова подключаться к мобильному телефону, если они явно не выходят из системы или не теряют ключ.

Метод входа - без генерации ключей

class Login(webapp.RequestHandler):
def post(self):
    args = json.loads(self.request.body)
    email = args['e']
    pwd = args['p']
    ret = {}
    user = User.gql('WHERE email = :1', email).get()
    if user and helpers.check_password(pwd, user.password):
        ret['ret_code'] = 0
        ret['dn'] = user.display_name
    else:
        ret['ret_code'] = 1

    self.response.headers['Content-Type'] = 'application/json'
    self.response.out.write(json.dumps(ret))

Ответы

Ответ 1

Я думаю, вы должны использовать функции webapp2, обеспечивающие реализацию вашей пользовательской регистрации.

from webapp2_extras import auth
from google.appengine.api import users

class RegisterHandler(webapp2.RequestHandler):
    def post(self):
        email=self.request.POST['email']
        password=self.request.POST['password']

        #Let webapp2 handle register and manage session
        user = auth.get_auth().store.user_model.create_user('own:'+str(email), password_raw=password,email=email)
        #user (True, User(key=Key('User', 80001), auth_ids=[u'own:[email protected]'],email='[email protected]',password=u'hashed_password',...))

        if not user[0]: #user is a tuple
            self.response.write(user[1]) # Error message
        else:
            #You can extend your User Model e.g UserProfile(User): or have a UserProperty in your profile model as the example.  
            profile=UserProfile(user=users.User(user[1].email)).put()

            self.response.write(str(profile.key()))
class LoginHandler(webapp2.RequestHandler): 

    def post(self):

        email = self.request.POST.get('email')
        email = 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:
            auth.get_auth().get_user_by_password('own:'+email, password)
            #Return user_session with User id, 
        except InvalidPasswordError, InvalidAuthIdError:
            #Error

Вы можете проверить, что пользователь зарегистрирован:

if auth.get_user_by_session():
    #Logged in      
else:
    #Not logged in

В вашем клиентском приложении (Android, IOS). Вам нужно только сохранить файл cookie ответа и отправить его для каждого запроса подстроки.

Удачи:)

Ответ 2

Взгляните на дополнительные приложения webapp2 и webapp2 с сеансами, auth и JSON

Ответ 3

Я не понимаю, зачем вам нужен сеанс? Сеансы в App Engine сохраняются в хранилище данных, поэтому, если вы можете сохранить ваши запросы без гражданства, я призываю вас сделать это.

Поскольку у вас будет собственная пользовательская служба, которая будет проверять подлинность пользователей, я предлагаю вам использовать аутентификацию Digest, поскольку секрет никогда не включается в запрос.

Существуют библиотеки, реализующие дайджест для большинства клиентских и серверных платформ.

Ответ 4

Если вы явно не хотите использовать сеансы и т.д., вы можете просто использовать хранилище данных. Попробуйте следующее:

  • Получите уникальный идентификатор устройства/адрес электронной почты, чтобы идентифицировать каждого уникального пользователя.
  • По запросу от конкретного пользователя создайте случайный ключ проверки подлинности и сохраните его в соответствии с идентификатором пользователя/идентификатором пользователя и, вероятно, текущей меткой времени и флагом loggedIn.

SO у вас есть:

User email/id: [email protected]
password: xxxxxxxxxx
Key : 2131231312313123123213
Timestamp: 20:00 12-02-2013
loggedIn : boolean value

Это может быть модель базы данных. Теперь, когда пользователь входит в систему:

  • Проверьте электронную почту, комбинацию паролей.
  • Если допустимо, создать случайный ключ и обновить хранилище данных с помощью нового ключа
  • обновить временную метку с текущим временем и установить loggedIn на True
  • Теперь верните ключ обратно клиенту (Android/iPhone) в объект JSON.

Теперь при каждом запросе проверьте полученный ключ на тот, который находится в вашем хранилище данных, и если для параметра loggedIn установлено значение true. Если оба ОК, обработайте запрос.

Кроме того, при выходе из системы:

  • Просто установите флаг loggedIn в хранилище данных False.

Надеюсь, что это поможет:)

Ответ 5

Попробуйте gae-sessions для управления сеансом. Он создает безопасные файлы cookie для вас и позволяет вам легко связывать данные с каждым пользователем. Просто укажите свою собственную логику для первоначальной аутентификации.

Он был специально создан для App Engine и довольно популярен и супер быстрый/масштабируемый.

https://github.com/dound/gae-sessions

Ответ 6

Есть много способов сделать это.

1) Когда вы проверяете данные регистрации пользователей, если они проверяют, вы можете создать случайный UUID или строку и сохранить объект User в memcache со случайной строкой в ​​качестве ключа и пользовательского объекта в качестве значения. Затем верните случайную строку вместе с заголовками ответов. На мобильном устройстве, когда вы разбираете ответ, получите этот заголовок и сохраните его в локальном кеше. По всем дальнейшим запросам продолжайте отправлять этот ключ обратно в заголовок запроса, а в контроллере вы получите объект User из memcache с помощью этого ключа и продолжите. Если объект не находится в memcache, вы можете отправить ответ, который предлагает пользователю войти в систему.

2) Если вы не хотите использовать memcache, вы можете сохранить объект User в сеансе и на стороне клиента, в то время как синтаксический анализ ответа получит идентификатор сеанса из ответа. Его обычно JSESSIONID. Затем сохраните это и отправьте его другим запросам. В контроллере вы можете проверить, не имеет ли текущий сеанс пользовательский объект принудительный вход.

1) Еще один способ: вернуть ключ appengine для пользователя вместе с ответом и отправить его повторно.

Просто откройте ответ от заголовка ответа google. Затем получите заголовок SESSIONID/JSESSIONID, сохраните и добавьте поле с тем же именем и значением для всех последующих заголовков запросов. Это самый простой способ.

Мой первый ответ на stackoverflow и без кода exapmles, dangit, если только я знал python.