AppEngine Python - 如何确保用户注册唯一的用户名 [英] AppEngine Python - how to ensure that users register with unique uersnames

查看:249
本文介绍了AppEngine Python - 如何确保用户注册唯一的用户名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个新的AppEngine / Python HRD应用程序。在这个应用程序中,我需要确保注册的每个用户都不能使用已经分配给另一个用户的名称,并且如果两个用户在同一时刻尝试使用相同的用户名注册,则只有其中一个用户被给予用户名。

如果我要将所有用户名放在一个实体组中并使用事务来确保唯一性,那么在事务中写入用户名/对象可能会减慢所有用户注册过程。所以这种方法似乎并不是一个好主意。



另一个选择是使用用户名作为关键字,它的缺点是可能使得用户稍后更改其用户名。

在AppEngine中实现此功能的最佳/标准方法是什么?

解决方案

好的。 您不需要全部粘住在一个大的实体组中保证一致性的用户名。



使用户名成为管理登录的数据存储实体的键。



然后在一个事务中。


  1. 使用用户名作为键(这是一个一致的操作)
    如果您发现它,显然它不可用如果找不到,则创建新的登录实体。


    另外,如果您使用电子邮件地址,那么它很可能意味着没有任何冲突。我不确定为什么可见的昵称名称必须是唯一的,但是你可能有一个很好的理由。

    每个实际的用户对象都可以有一个系统生成唯一的id, (这是一个与登录实体分开的实体)。



    如果你确实是偏执狂,那么使用memcache CAS操作可以有效地充当用户密钥的锁并阻止同时操作,但我认为这不是必要的。



    实体可能看起来像



    <$ p $ b $ 类登录(ndb.Model):
    #其他东西neede认证等。
    user = ndb.KeyProperty(User)

    @ ndb.transactional(XG = TRUE)
    @classmethod
    高清create_login(CLS,用户名):
    #也许传递额外的用户信息
    键= ndb.Key(CLS, keyname)
    login = key.get()
    如果登录:
    提升DuplicateUsernameError(用户名)

    登录=登录(key_name =用户名)
    user = User.create_user(login = login.key)
    login.user = user.key
    login.put()
    返回(登录,用户)


    class User(ndb.Model):
    login = ndb.KeyProperty(Login)#这个属性只是为了方便。
    昵称= ndb.StringProperty()
    #等

    @classmethod
    高清create_user(CLS,login_key):
    #是的,你会通过更多用户的东西。
    $ b $ user = cls(login = login_key)
    user.put()

    #唯一的用户密钥是系统生成的。
    返回用户

    这意味着只需要一个get()就可以获取登录名,其次是获取其余的用户信息,但比查询更便宜/更快。这也意味着如果您真的想要这样的功能,登录名称/代码可以随时更改而不会中断实际的用户实体。或者可能支持单个用户的多种登录方法 - 即Facebook和Twitter。这也意味着一个登录实体可以被移除并且随着时间的推移被其他人重新使用,并且如果需要系统完整性/历史记录,用户实体可以留下。


    I am designing a new AppEngine/Python HRD application. In this application, I need to ensure that each user that registers cannot use a name that has already been assigned to another user, and that if two users attempt to register with the same username at the exact same moment, that only one of them will be given the username.

    If I were to put all usernames in a single entity group and use transactions to ensure uniqueness, then the writing of the username/object in a transaction could potentially slow down all registration processes. So this approach doesn't seem like a good idea.

    Another option would be to use the username as the key, which has the disadvantage of possibly making it difficult for the user to later change their username.

    What is the best/standard approach to achieve this in AppEngine?

    解决方案

    Ok.

    You don't need to stick all the usernames in a big entity group to guarantee consistency.

    Make the username the Key of the datastore entity governing the login.

    Then inside a transaction.

    1. Try a get using the username as a key (this is a consistent operation) if you find it then obviously it's not available
    2. If not found then create the new login entity.

    As an aside if you used email addresses then it would more than likely mean no clashes ever. and I am not sure why visible nick names need to be unique, but then you probably have a good reason.

    Each actual user object can have a system generated unique id, (this is a separate entity to the login entity).

    If you are really paranoid, then look at using memcache CAS operations to effectively act as a lock on the username key and prevent simultaneous operations, though I don't think it would be necessary.

    Entities might look like

    class Login(ndb.Model):
        # other stuff neede for authentication etc..
        user = ndb.KeyProperty(User)
    
        @ndb.transactional(xg=True)
        @classmethod
        def create_login(cls,username):
            # maybe pass in extra user details
            key = ndb.Key(cls, keyname)
            login = key.get()
            if login:
                raise DuplicateUsernameError(username)
    
            login = Login(key_name=username)
            user =  User.create_user(login=login.key)
            login.user = user.key
            login.put()
            return (login,user) 
    
    
    class User(ndb.Model):
        login = ndb.KeyProperty(Login)  # this property is only for convenience.
        nickname = ndb.StringProperty()
        # etc
    
        @classmethod
        def create_user(cls,login_key):
            # yes you would pass in more user stuff.
    
            user = cls(login=login_key)
            user.put()
    
            # the unique user key is system generated.
            return user
    

    This means only a single get() is required to fetch a login, and second to get the rest of the user details but is much cheaper/faster than queries. It also means that the login name/code could be changed over time without disrupting the actual user entity if you really wanted such functionality. Or possibly support multiple login methods for a single user - ie facebook and twitter. It also means a login entity can be removed and login re-used by other people over time, and the user entity can stay if system integrity/history is required.

    这篇关于AppEngine Python - 如何确保用户注册唯一的用户名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆