2012-06-25 20 views
5

그래서 저는 python으로 jinja2 템플릿 플랫폼에서 google appengine 용으로 응용 프로그램을 작성하고 있습니다. 내 사이트에서 잘 작동하도록 OpenID를 받았고 사용자가 로그인 할 수있게하고 오른쪽 상단에 이메일/ID를 표시 할 수 있습니다.openid 사용자에게 추가 정보 제공

이제 사용자가 자신의 사용자 이름을 갖고 사이트 방문 및 사이트 영역에 대한 특정 게시물과 같은 추가 데이터를 저장할 수있게하려고합니다.

나는 사용자와 모든 것을 데이터베이스에 테이블을 만들 필요가 있음을 알고 있지만 OpenID를 사용하여이 작업을 수행하는 올바른 방법은 무엇입니까? 누군가가 처음으로 로그인 할 때 자동으로 사용자를 만들고 싶지만이 작업을 효율적으로 수행하는 방법을 잘 모릅니다. 데이터베이스에서 federated_identity를 확인하는 로그인 후 해당 페이지로 리디렉션하여 관리 할 수 ​​있다고 생각합니다. 이미 존재하는 경우 홈 페이지로 리다이렉트하지만 그렇지 않은 경우 새 사용자를 만듭니다.

누군가가 로그인 할 때마다 데이터베이스를 쿼리하지 않거나 꽤 괜찮은 방법 일 수있는 효율적인 방법이 있습니까?

답변

6

당신 말이 맞아요, 당신은 자신의 사용자 모델을 생성하고 추가 정보와 당신이 당신의 어플리케이션에 가지고있는 비즈니스 로직을 저장해야합니다. 당신이해야 할 모든 오픈 아이디로 로그인 후, 추가 username, name와 함께 등

(예 : federated_id) 독특한 무언가를 저장하는 것입니다, 특정 federated_id이 데이터 저장소에있는 경우 당신은 확인하고 당신은 것입니다 그 특정 user_db을 반환하거나 기본값을 사용하여 새 값을 만들고 새로 만든 user_db을 반환하십시오.

중요한 것은 귀하의 요청에 항상 users.get_current_user()이 아닌 귀하의 user_db 엔티티를 처리한다는 것입니다. 이는 기본적으로 읽기 전용이며 제한적이기 때문입니다.

다음은 또한 사용자가 로그인하고 None, 그렇지 않은 경우 자신의 user_db 개체를 반환합니다 get_user() 기능을 가진 base handler class을 보여 전체 예이다. 사용자가 처음 로그인려고하는 경우에, 새로운 user_db 엔티티 일부 기본값 (name, username, email, admin, federated_id)로 작성됩니다 :이 문제에 대한 여러 가지 접근 방법이있다

from google.appengine.api import users 
from google.appengine.ext import ndb 
import webapp2 

class User(ndb.Model): 
    name = ndb.StringProperty(required=True) 
    username = ndb.StringProperty(required=True) 
    email = ndb.StringProperty() 
    federated_id = ndb.StringProperty() 
    admin = ndb.BooleanProperty() 

class BaseHandler(webapp2.RequestHandler): 
    def get_user_db(self): 
    federated_user = users.get_current_user() 
    if not federated_user: 
     return None 
    user_db_qry = User.query(User.federated_id == federated_user.user_id()) 
    user_db_list = user_db_qry.fetch(1) 
    #If that returns non empty list, then return the first element which is the user_db 
    if user_db_list: 
     return user_db_list[0] 

    #Otherwise create a new user_db entity, with default values and return 
    user_db = User(
     name=federated_user.nickname().title(), 
     username=federated_user.nickname(), 
     email=federated_user.email(), 
     federated_id=federated_user.user_id(), 
     admin=users.is_current_user_admin(), 
    ) 
    user_db.put() 
    return user_db 

class MainHandler(BaseHandler): 
    def get(self): 
    self.response.headers['Content-Type'] = 'text/html' 
    if self.get_user_db(): 
     self.response.out.write('Hello, %s!</br>' % self.get_user_db().name) 
     self.response.out.write('<a href="%s">Logout</a>' % (users.create_logout_url(self.request.uri))) 
    else: 
     self.response.out.write('Hello, stranger!<br>') 
     self.response.out.write('<a href="%s">Login</a>' % (users.create_login_url(self.request.uri))) 

app = webapp2.WSGIApplication([('/', MainHandler)], 
           debug=True) 

, 그러나 저는 이것이 이것이 좋은 아이디어라고 생각합니다.

+0

괜찮습니다. 오늘 오후에 테스트 해보고 어떻게되는지 확인해 드리겠습니다. – clifgray

+0

이 행의 내용을 설명해 주시겠습니까? user_db_list = User.query (User.federated_id == federated_user.user_id()). fetch (1) – clifgray

+0

@clifgray 특정 Federated_id에 대한 사용자가 자신의 모델에서 검색하는 경우 ... 결과가 빈 목록이 아닌 경우 우승자가 있습니다. otherwiser 우리는 하나의 엔티티를 만든 다음 반환해야합니다. .. – Lipis