2009-06-23 100 views
1

我的应用程序要求用户使用他们的谷歌帐户登录。检测用户首次登录到应用程序(Google Appengine)

我有这一套在我App.yamp文件:

  • 网址:/user/.*
    脚本:user.py
    登录:需要

现在,当任何用户尝试访问/user/secret.py下的文件,他需要通过谷歌进行身份验证,这将在成功验证后将用户重定向回到/user/secret.py。现在我面临的问题是用户被重定向回应用程序时,我无法确定这是用户第一次登录还是我的网站的常规用户,他们已经从用户处重新回来google通过users.get_current_user()传递的对象。

因此,我需要维护数据存储中的状态以检查用户是否已经存在或不是每次。如果他不存在,我需要用其他应用程序特定设置创建一个新条目。

我的问题是:有一些更简单的方法来处理这个问题吗?而不必查询数据存储区来判断这是第一次用户还是常规用户?

回答

1

您是否可以在用户首次登录时检查此Cookie?如果他们是一个新用户,它不会在那里,但如果他们是一个旧用户,它会。这并不是100%准确的,因为有些用户可能会清除他们的cookie,但可能会根据您想要达到的目标来做。

如果您在应用程序中使用Django managing Cookies is pretty straightforward

+0

饼干是一个很好的选择。我希望应用引擎中有一些可以直接告诉我的东西,例如用户类中的某个属性? – MathOldTimer 2009-06-23 10:58:33

2

不,Google不会跟踪用户是否登录过您的应用程序。由于您大概需要针对用户存储某种状态,最简单的方法是尝试从数据存储中检索用户的记录。如果他们没有,可以将它们发送到注册屏幕以收集此信息。您可以使用memcache来缓存用户的信息并避免额外的数据存储往返。

2

我倾向于使用我自己的用户和会话manangement

对于我的网络处理,我会附上一个装饰叫做会话和一个叫做授权。会话装饰器将为每个请求附加一个会话,并且授权装饰器将确保用户被授权

(谨慎的一句话,授权装饰器特定于我如何开发我的应用程序 - 用户名是第一个在大多数的请求参数)

因此,例如,网络处理程序可能看起来像:

class UserProfile(webapp.RequestHandler): 
    @session 
    @authorize 
    def get(self, user): 
    # Do some funky stuff 
    # The session is attached to the self object. 
    someObjectAttachedToSession = self.SessionObj.SomeStuff 
    self.response.out.write("hello %s" % user) 

在上面的代码中,会话装饰重视基础是存在于饼干,我需要一些会话东西请求。如果会话是正确的,授权标头将确保用户只能访问该页面。

的装饰代码低于:

import functools 
from model import Session 
import logging 

def authorize(redirectTo = "/"): 
    def factory(method): 
     'Ensures that when an auth cookie is presented to the request that is is valid' 
     @functools.wraps(method) 
     def wrapper(self, *args, **kwargs): 

      #Get the session parameters 
      auth_id = self.request.cookies.get('auth_id', '') 
      session_id = self.request.cookies.get('session_id', '') 

      #Check the db for the session 
      session = Session.GetSession(session_id, auth_id)   

      if session is None: 
       self.redirect(redirectTo) 
       return 
      else: 
       if session.settings is None: 
        self.redirect(redirectTo) 
        return 

       username = session.settings.key().name() 

       if len(args) > 0:    
        if username != args[0]: 
         # The user is allowed to view this page. 
         self.redirect(redirectTo) 
         return 

      result = method(self, *args, **kwargs) 

      return result 
     return wrapper 
    return factory 

def session(method): 
    'Ensures that the sessions object (if it exists) is attached to the request.' 
    @functools.wraps(method) 
    def wrapper(self, *args, **kwargs): 

     #Get the session parameters 
     auth_id = self.request.cookies.get('auth_id', '') 
     session_id = self.request.cookies.get('session_id', '') 

     #Check the db for the session 
     session = Session.GetSession(session_id, auth_id)   

     if session is None: 
      session = Session() 
      session.session_id = Session.MakeId() 
      session.auth_token = Session.MakeId() 
      session.put() 

     # Attach the session to the method 
     self.SessionObj = session   

     #Call the handler.   
     result = method(self, *args, **kwargs) 

     self.response.headers.add_header('Set-Cookie', 'auth_id=%s; path=/; HttpOnly' % str(session.auth_token)) 
     self.response.headers.add_header('Set-Cookie', 'session_id=%s; path=/; HttpOnly' % str(session.session_id)) 

     return result 
    return wrapper 

def redirect(method, redirect = "/user/"): 
    'When a known user is logged in redirect them to their home page' 
    @functools.wraps(method) 
    def wrapper(self, *args, **kwargs): 
     try:  
      if self.SessionObj is not None: 
       if self.SessionObj.settings is not None: 
        # Check that the session is correct 
        username = self.SessionObj.settings.key().name() 

        self.redirect(redirect + username) 
        return 
     except: 
      pass 
     return method(self, *args, **kwargs) 
    return wrapper 
1

我同意,管理自己的身份验证的用户是解决这个问题的最好办法。根据您的应用程序范围,显然至少应包含一个AuthUser(Model)类,其中包含已通过您的帐户登录的用户的UserProperty。

... 
class AuthUser(db.Model): 
    user = UserProperty(required=True) 
... 

然后,当在刚刚

... 
user = users.get_current_user() 
user_exists = AuthUser.gql('where user = :1', user) # or easy check db.GqlQuery("select __key__ from AuthUser where user = :1", user) 
if user_exists: 
    # do user has been before stuff 
else: 
    # do first time user stuff 
... 

或者一个超级简单的方法做,这是对你的网站模型具有的ListProperty(users.User)用户登录,然后你可以很容易地检查列表以查看用户是否已加入您的应用程序。

... 
class SiteStuff(db.Model): 
    auth_users = ListProperty(users.User) 
... 

当他们登录时:检查他们是否在列表中;如果没有,你将它们添加到列表中,放入()它并为第一次用户做所需的任何事情。如果你发现他们在那里,然后做其他的东西。

相关问题