Обработка сеансов в 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.