15

我开始编写一个应用程序,移动应用程序(Android/IPhone)将通过一系列使用 JSON 的 Web API 调用与 GAE 后端(Python)进行通信。

我无法使用 Google 帐户进行身份验证,因此我需要实现自己的身份验证。我知道如何做到这一点,但我不确定是否有更好的方法。

任何人都可以提供一些关于如何实现以下目标的代码示例/建议吗?

方法

  1. 移动应用程序调用服务器上的登录方法,该方法验证并在商店中创建会话密钥并将其返回给应用程序 -不确定如何生成密钥/会话或它应该在请求/响应中的位置。
  2. 在每次调用时,应用程序都会将此密钥传递给服务器以进行身份​​验证,并在通过时允许该操作。
  3. 除非用户明确注销或丢失密钥,否则用户不必再次登录移动设备。

登录方法 - 无需生成密钥

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))
4

6 回答 6

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:useremail@mail.com'],email='useremail@mail.com',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 并为每个子序列请求发送它。

祝你好运 :)

于 2012-06-26T06:55:04.537 回答
0

尝试gae-sessions进行会话管理。它为您创建安全 cookie,并允许您轻松地将数据与每个用户相关联。只需为初始身份验证提供您自己的逻辑。

它是专门为 App Engine 构建的,非常受欢迎并且超级快速/可扩展。

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

于 2013-02-18T10:15:50.080 回答
0

我看不出你为什么需要一个会话?App Engine 上的会话持久保存在数据存储中,因此如果您可以保持请求无状态,我鼓励您这样做。

由于您将拥有自己的用户服务来对用户进行身份验证,因此我建议您使用摘要式身份验证,因为请求中永远不会包含密钥。

有一些库为大多数客户端和服务器平台实现了 Digest。

于 2013-01-06T05:40:11.710 回答
0

查看带有会话、身份验证和 JSON 的 webapp2 和 webapp2 extras

于 2012-06-24T17:40:27.433 回答
0

如果您不想明确使用 Sessions 等,您可以简单地使用 Datastore。试试这个:

  1. 获取唯一的设备 ID/电子邮件以识别每个唯一用户。
  2. 根据特定用户的请求,生成随机身份验证密钥,并将其存储到用户的电子邮件/设备 ID 以及可能的当前时间戳和登录标志。

所以你有了:

User email/id: someone@example.com
password: xxxxxxxxxx
Key : 2131231312313123123213
Timestamp: 20:00 12-02-2013
loggedIn : boolean value

这可以是数据库模型。现在每当用户登录时:

  • 检查电子邮件,密码组合。
  • 如果有效,生成随机密钥,并使用新密钥更新数据存储
  • 用当前时间更新时间戳,并将loggedIn设置为True
  • 现在将密钥以 JSON 对象的形式返回给客户端(Android/iPhone)。

现在,在每个请求上,检查接收到的密钥与数据存储区中的密钥是否相符,以及是否将loggedIn标志设置为 true。如果两者都OK,则处理请求。

此外,在注销时:

  • 只需将数据存储中的loggedIn标志设置为False。

希望这可以帮助 :)

于 2013-02-05T07:44:41.400 回答
0

有很多方法可以做到这一点。

1)当您检查用户登录详细信息时,您可以创建一个随机 UUID 或字符串,并将用户对象存储在内存缓存中,其中随机字符串作为键,用户对象作为值。然后返回随机字符串以及您的响应标头。在移动端解析响应时,获取此标头并将其存储在本地缓存中。在所有进一步的请求中,请继续在请求标头中将此密钥发送回,并在您的控制器中使用此密钥从 memcache 获取用户对象并继续。如果对象不在内存缓存中,您可以发回提示用户登录的响应。

2)如果您不想使用memcache,您可以在解析响应时将用户对象存储在会话中和客户端,从响应中获取会话ID。它通常是 JSESSIONID。然后存储它并用进一步的请求重新发送它。在控制器中,您可以检查当前会话是否具有用户对象,否则强制登录。

1)另一种方法是将用户的appengine密钥与响应一起返回并重新发送。

只是谷歌从响应中获取响应头。然后获取 SESSIONID/JSESSIONID 标头,存储并将具有相同名称和值的字段添加到所有进一步的请求标头中。那是最简单的方法。

我在 stackoverflow 上的第一个答案,没有代码示例,如果我知道 python,dangit。

于 2013-03-19T22:24:17.867 回答