Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Sessions on Google App Engine with Android/IPhone

I'm starting to write an app whereby a mobile app (Android/IPhone) will communicate with the GAE backend (Python) through a series of Web API calls using JSON.

I can't use Google Accounts for authentication so I need to implement my own auth. I have an idea of how to do this, but I'm not sure if there is a better way.

Can anyone help with some code examples/suggestions of how to achieve the below please?

Method

  1. Mobile app calls a Login method on the server which authenticates and creates a session key in the store and returns this to the app - not sure how to generate the key/session or where on the request/response it should be.
  2. On every call, the app passes this key for the server to authenticate and allows the action if it passes.
  3. User should not have to login on mobile again unless they explicitly logout or lose the key.

Login Method - without key generation

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))
like image 735
arrkaye Avatar asked Jun 24 '12 16:06

arrkaye


1 Answers

I think you should use features webapp2 providing to implement your custom registration.

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

You can check user logged in by:

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

On your client application(Android, IOS). You only have to store the response cookie and send it for every sub sequence requests.

Good luck :)

like image 167
Cuong Thai Avatar answered Sep 27 '22 19:09

Cuong Thai