2015-01-01 2 views
0

Google App Engine 용 전자 메일 주소 python 파일을 확인하고 있습니다. (나중에 나는 장고에 물건이 있다는 것을 알고 있지만 그것이 내가 배운 방법이기 때문에 나는 내 자신을 쓰고 싶다)브라우저에서 호출 할 때 GAE에 대한 mySQL UPDATE가 작동하지 않습니다.

다음은 파이썬 코드이다. 이 코드는 "전자 메일 계정 확인"을 반환합니다.이 쿼리는 쿼리가 작동하는 것처럼 보입니다. 그러나 데이터베이스의 "활성"열을 보면 여전히 0입니다.

데이터베이스 자체에 logging.info ("% s", db_query)라는 쿼리 문자열을 실행하면 작동하며

다른 모든 파이썬 코드 (업데이트 포함)는 제대로 작동하지만 파이썬 파일은 내 IOS 응용 프로그램에서 호출되며이 파일은 브라우저에서 호출됩니다.

#Make the libs folder with 3rd party libraries and common methods 
import sys 
sys.path.insert(0, 'libs') 

#Imports 
import logging 
import webapp2 
from django.utils.html import strip_tags 
import common 
import MySQLdb 
import json 

VERIFIED_HTML = """\ 
<html> 
    <body> 
    <h1>Email Account Verified</h1> 
    </body> 
</html> 
""" 

ERROR_HTML = """\ 
<html> 
    <body> 
    <h1>ERROR</h1> 
    </body> 
</html> 
""" 


class VerifyEmail(webapp2.RequestHandler): 
    def get(self): 
     user_email = strip_tags(self.request.get('user_email').lower().strip()) 
     user_activation_hash = strip_tags(self.request.get('user_activation_hash').strip()) 

     logging.info("User Email = %s", user_email) 
     logging.info("User Activation Hash = %s", user_activation_hash) 

     #Insert the information into the users table 
     #Get the database connection to Google Cloud SQL 
     db = common.connect_to_google_cloud_sql() 
     db_cursor = db.cursor(MySQLdb.cursors.DictCursor) 

     #Check to see if user already exists 
     #Query for user 
     db_query = """SELECT \ 
         email, activation_hash \ 
         FROM users WHERE email='%s' AND activation_hash='%s'""" %   (user_email, user_activation_hash) 
    db_cursor.execute(db_query) 

     #If there is one record containing the username check password 
     if(db_cursor.rowcount == 1): 
      db_query = """UPDATE users SET active=%s WHERE email='%s';""" % (1, user_email) 
      logging.info("%s" % db_query) 
      if(db_cursor.execute(db_query)): 
       self.response.write(VERIFIED_HTML) 
      else: 
       self.response.write(ERROR_HTML) 

     else: #either no user, or activation_hash doesn't match 
      self.response.write(ERROR_HTML) 

연결 Google 클라우드 SQL

def connect_to_google_cloud_sql(): 
    #hostname = DEV_DB_HOSTNAME 
    #hostname = PROD_DB_HOSTNAME 

    db_username = 'dummy_user' #not real 
    db_password = 'dummypassword' # not real 


    #If PROD or Deployed Testing, use unix_socket 
    if(os.getenv('SERVER_SOFTWARE') and os.getenv('SERVER_SOFTWARE').startswith('Google App Engine/')): 
     db = MySQLdb.connect(unix_socket='/cloudsql/' + _DATABASE_HOSTNAME, db='dummydbname', user=db_username, passwd=db_password) 
    else: #Local Testing uses host 
     db = MySQLdb.connect(host=_DATABASE_HOSTNAME, port=3306, db='dummydbname', user=db_username, passwd=db_password) 

    logging.info("Got DB Connection") 

    return db 

어떤 제안에? 그것은 GAE Cloud SQL Privlesges입니까? 내 로컬 IP에서 실행되는 로컬 앱 엔진으로 브라우저를 사용했기 때문에 어쩌면 ???

+1

오픈 SQL 인젝션 벡터의 어떤 * 완벽한 예입니다. –

+0

나는 배우고있다. 도움을 받고 더 많은 정보를 제공하고자한다면 감사하겠습니다. – lr100

+2

@ lr100, Daniel의 요점은 "문자열 형식의 SQL 문을 만들지 마라"- 대신에 % s 자리 표시자를 사용하고 두 개의 인수 형식의 execute (두 번째 인수로 값 튜플을 전달) . 코드의 중요한 취약점은 그대로 있지만 사용자가 관찰 한 오류에 직접적인 영향을 미치지는 않습니다. –

답변

1

쿼리를 실행 한 후 MySQLdb 커서에 .commit()을 호출해야합니다. 이것이 업데이트에 실패한 이유입니다. 트랜잭션 내부에서 업데이트되지만 트랜잭션을 커밋하지 않고 코드가 끝나면 사용자에게 업데이트 성공을 알렸음에도 불구하고 DB에 대한 변경 사항은 롤백됩니다.

다음 방법을 사용하여 커서를 사용할 때 커밋을 보장 할 수도 있습니다. db_cursor.autocommit(True).

+0

정말 고마워요 !!! 나는 어리석은 실수를 할 때가 싫지만 때로는 또 다른 한 쌍의 눈을 가져 간다. – lr100