先貼完整代碼,個人寫的一般,請諒解。
@coroutine def put(self): # 修改區域信息 req_body = self.request.body assert req_body, 'request body is None' info = loads(req_body) _id = info.get('_id') name = info.get('name') address = info.get('address') assert _id, '_id argument not given' assert name or address, 'argument lost' _sql = "UPDATE area SET %s" param = [] _param = [] if name: param.append("name=%s") _param.append(name) if address: param.append("address=%s") _param.append(address) _param.append(_id) sql = _sql % (",".join(param)) + " WHERE _id=%s" with StoreContext() as store: ctx = yield store.begin() try: yield ctx.execute(sql, tuple(_param)) yield ctx.commit() except: app_log.error("update area failed, body={0}, details: {1}".format(info, traceback.format_exc())) yield ctx.rollback() self.write_rows()
通常在寫代碼時會有以下幾個誤入點。
誤入點1:
由於需要修改的字段不確定,在初始化SQL時不要將WHERE條件加入,像下面這么會產生SQL注入
_sql = "UPDATE area SET %s WHERE _id=%s" param.append("name=%s") param.append("address=%s") _sql % (",".join(param), _id) # 如果_id傳入的是_id="1 or 1=1",_sql則會變成 'UPDATE area SET name=%s,address=%s WHERE _id=1 or 1=1'
誤入點2:
在拼接字段時,直接將傳入的值拼入字符串中,像下面這樣會有問題
param.append("name=%s" % name) # 如果遇到中文時,字段的內容會變成下面這樣 "name=u'\\u534e\\u4e1c1',address=u'http://10.0.0.111'" # 這樣就不說了,直接拋錯
最好的做法是將要拼入的字段和對應的值放在兩個不同的列表中,將SQL拼完整后,調用execute方法。
_sql = 'UPDATE area SET name=%s,address=%s WHERE _id=%s' _param = ("xxx", "xxx", "xxx") # execute方法會自己處理注入問題 ctx.execute(sql, _param)
今天主要是遇到拼接時出現中文亂碼問題,最好的處理方式是將所有的值放到execute方法里面,不要畫蛇添足的自己去拼接,產生不必要的麻煩。