Posts

shop_platform - 部署到 Heroku 後,session 有問題

問題描述 部署到 heroku 後,出現一些奇怪的現象: 輸入正確登入資訊,按下登入按鈕後: 有時候會登入成功,跳轉到首頁,但切換幾個畫面後,又變成沒有登入的狀態 跳轉到首頁,但仍是未登入狀態,也沒有出現任何 flash 訊息。切換幾個畫面後,出現遲來的 flash 訊息 仍是跳轉到登入頁面,沒有出現任何 flash 訊息 在未登入狀態下,將物品加入購物車(此時購物車內容會存在 session)。點選購物車頁面後: 有時候會跳轉到首頁,也沒有出現任何 flash 訊息。切換幾個畫面後,出現遲來的 flash 訊息 成功顯示購物車中的商品,但若繼續點選購物車頁面,過沒多久就提示「購物車中沒有商品」 上述操作(導覽列判斷使用者是否已登入、flash、未登入時的購物車),多半是跟 session 有關係,讓我有一種「cookie 或 session 好像會突然出現,又突然消失」的感覺。 另外,如果在本地也跟 heroku 一樣使用 gunicorn "app:create_app()" 指令開啟伺服器,一切功能都正常,無法重現 heroku 上的問題。 查資料 Flask sessions not persisting on heroku - stackoverflow Application Server、WSGI Server、Web Server 之間的關係 nginx+gunicorn/uwsgi+python web 的前世今生 Flask想上線? 你還需要一些酷東西 Heroku gunicorn flask login is not working properly - stackoverflow gunicorn 19 with WebSocket on Heroku These applications based on the Flask-SocketIO extension are stateful. If multiple workers ar...

ModernWeb 2021 與會隨筆(10/12~10/15)

Modern Web 2021 共筆 10/13 依照古法、純手工打造的視訊聊天網站,不純免錢!/ GitHub 範例程式碼 確認是否有在線上:long polling or websocket(比較建議用後者) 取得麥克風和鏡頭權限: MediaDevices.getUserMedia() 用 WebRTC 傳送串流資料:socket.io Signal Server:peer.js。Signal Sever 的作用類似媒人婆,介紹雙方的資訊(Session Description Protocol,SDP,紀錄 IP、agent、decode、encode 等資訊),雙方認識後就讓他們點對點直接溝通,不必再透過媒人婆溝通 如果是內網 IP,會透過 NAT(Network Address Translation)轉成 public IP STUN(Simple Traversal of UDP over NATs)、處理不同網路的連線(via TURN server):不知道這兩個是啥,暫且搜尋到這篇介紹: 明辨STUN/TURN協定 輕鬆跨越NAT建立連線 10/14:測試 八個沒人告訴你的網頁自動化測試挑戰/ 林佳妤(Melo) 主要針對 code less 的工具而言(用螢幕錄製的方式製作 test case),例如 Selenium IDE 測試「滑鼠滑過元件後要發生指定變化」,錄製時會錄到非目標的「mouse over」事件。解一:選擇目標 mouse over。解二:調整敏感度 按鈕被別的東西擋住,使用者按不到,但測試按得到,造成測試通過,但其實功能不合格。解:verify visibility 如何確認按鈕已經 disable? 有 HTML 和 CSS 兩種方法可以 disable 按鈕,檢查是否有使用其中一種方法 HTML:disable 屬性 CSS: 解一:用 get computed style 計算 pointer-events 屬性(需要比較多程式背景知識)。解二:verify css(code-less) ...

shop_platform - sqlalchemy.exc.TimeoutError

發生的問題 啟動伺服器後,第二十一次請求「需要查詢資料庫」的頁面時,會出現「sqlalchemy.exc.TimeoutError: QueuePool limit of size 10 overflow 10 reached, connection timed out, timeout 30.00 (Background on this error at: https://sqlalche.me/e/14/3o7r )」的錯誤訊息。如果請求是不需要查詢資料庫的(例如靜態檔案或前往登入頁面),就不會發生此錯誤。 把 size 和 overflow 設定成更小的數字,可以更快重現這個錯誤 。 感覺起來,就像查詢完資料庫以後,沒有把 connection 釋出一樣,導致「size + overflow」是多少,就只能查詢多少次資料庫。 發現瀏覽器每向伺服器請求一次「需要查詢資料庫」的頁面,在 MySQL Workbench 用 show PROCESSLIST; 指令的查詢結果就會多出一筆資料,筆數達到 size + overflow 時,若再次請求「需要查詢資料庫」的頁面,就會噴 QueuePool limit of size 10 overflow 10 reached 的錯誤。關閉伺服器時,那幾筆資料才會被刪除。 嘗試過但失敗的方法 app.run(debug=False) 自己註冊一個關閉 session 的函式 @app.teardown_appcontext # 改成 @app.teardown_request 也沒用 def teardown_db(exception): db.session.remove() # 改成 db.session.close() 也沒用 print('***** session.remove') # 這一行有印出來,所以此函式有被執行 把 FLASK_ENV=development 拿掉 ,於是 FLASK_ENV 變成預設的 production app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True 終於成功的方法 第一種方法:用 Ap...

PyCon Taiwan 2021 與會隨筆

PyCon Taiwan 2021:大會之後會將影片上傳至 Youtube Day 1 成功地測試失敗 需求是要修理某個折扣的邏輯,但講者發現 api 傳來的資料是 list,猜測可能會傳過來不只一組折扣,所以用「迭代 list 中所有項目」的方式處理。上線後發現,果然沒猜錯,會傳過來不只一組折扣。如果當時沒有迭代整個 list,而只處理 list[0] 這組折扣,那就又要修 bug 了。 使用 Pytest 進行單元測試 python 內建 unitest 模組。pytest 套件支援 unitest 的 test case,在使用上 pytest 的語法比較方便,功能也比較強大。 參考書:The Art of Unit Testing 出口驗證有三種: 檢查函式的 output 檢查函式的 private property。若沒有 getter 可存取該 property,會比較麻煩一點。不過 python 沒有真正的 private property,處理起來比較容易。 函式的 return 就是呼叫外部 api。此時可以模擬外部 api,並記錄函式如何呼叫 api,這樣就能檢查呼叫的方式是否正確。 以前沒有想過「exception也要測試」這件事 原來測試碼覆蓋率,是有套件可以幫我們計算的。 Lightning Talks Patrick:用 Python 解決 iOS 14 之亂所帶來的數位廣告問題 塔圖科技針對「第三方 cookie 停用,網站需要在後端把資料送去給 FB」而推出了一個解決方案,讓網站不需要更動後端的程式碼,就可以送資料給 FB。我目前主要是學習網站後端的技能,這個消息透露了,第三方 cookie 停用,替代方案可能會需要由網站的後端工程師完成。 DennySORA:挖掘 asyncio 時的 try, except, else 與 finally 的小發現 原來 try-except-finally ,在不同的地方 return,會出現各種意料之外的效果。嚇得我立刻去搜尋到這篇文章 Python: 浅析 return 和 fin...

shop_platform - 對電商業務流程不熟,而不確定該怎麼處理的地方

串接藍新金流 使用者用藍新金流刷信用卡付款。伺服器收到藍新金流回傳的 TradeInfo 與 TradeSha,TradeInfo 雜湊後的值與 TradeSha 不符。Status 是 Success 所以使用者應該已經付錢了,這個時候要怎麼處理?先退錢給使用者嗎? TradeInfo 雜湊後的值與 TradeSha 相符,但付款金額和訂單上的金額不一樣時,要怎麼辦?(若排除商業邏輯寫錯的可能,這種情況,可能是 HashKey 和 HashIV 外洩,導致使用者可以自己修改 post 給藍新金流的 TradeInfo 與 TradeSha)。需要考慮這種可能性嗎? 藍新金流回傳的 TradeInfo 裡包含許多付款資訊。我應該把哪些付款資訊存到資料庫裡?記錄這些付款資訊是為了處理什麼問題?

shop_platform - 串接藍新金流:TradeSha

Image
(本文使用的語言為 python 3) 文件:藍新金流 > API 文件下載 > 多功能收款 MPG。我下載時,版本是 1.6 TradeSha 是什麼 根據文件第 33 頁的第一個表格,需要傳送給藍新金流的參數共有四個,其中一個就是 TradeSha: 根據文件第 70 頁,得到 TradeSha 的方法,是把 TradeInfo 前面加上 HashKey,後面加上 HashIV,然後用 SHA256 做雜湊,接著把所有英文字母轉成大寫。這樣就是合格的 TradeSha。 test case 為: trade_info = 'ff91c8aa01379e4de621a44e5f11f72e4d25bdb1a18242db6cef9ef07d80b0165e476fd1d9acaa53170272c82d122961e1a0700a7427cfa1cf90db7f6d6593bbc93102a4d4b9b66d9974c13c31a7ab4bba1d4e0790f0cbbbd7ad64c6d3c8012a601ceaa808bff70f94a8efa5a4f984b9d41304ffd879612177c622f75f4214fa' key = '12345678901234567890123456789012' iv = '1234567890123456' expect_output = 'EA0A6CC37F40C1EA5692E7CBB8AE097653DF3E91365E6A9CD7E91312413C7BB8' TradeSha 的作用,我猜是藍新金流用來檢查他們收到的 TradeInfo 是否有被篡改。如果有被篡改,他們自己對 TradeInfo 雜湊後的結果,會跟我們傳過去的 TradeSha 值不同。 實作 from Crypto.Hash import SHA256 def get_trade_sha(trade_info: str, key: str = HashKey, iv: str = HashIV) -> str: # 串接 HashKey、TradeSha、HashKey msg = f'H...

shop_platform - 串接藍新金流:TradeInfo

Image
(本文使用的語言為 python 3) 文件:藍新金流 > API 文件下載 > 多功能收款 MPG。我下載時,版本是 1.6 TradeInfo 是什麼 根據文件第 33 頁的第一個表格,需要傳送給藍新金流的參數共有四個,其中一個就是 TradeInfo: 需要放進 TradeInfo 裡的參數欄位,如文件第 33~37 頁所列。準備好這些參數欄位後,要幫這些參數欄位加密,加密後的結果,才是要傳送給藍新金流的 TradeInfo。 加密 根據文件第 65~66 頁,可以看到,要先把參數欄位整理成 query string 的格式,才進行 AES 加密。AES 加密採用 CBC 模式,padding 的 blocksize 是 32。然後把加密後的結果轉成 16 進位。test case 為: data = { 'MerchantID': 3430112, 'RespondType': 'JSON', 'TimeStamp': 1485232229, 'Version': 1.4, 'MerchantOrderNo': 'S_1485232229', 'Amt': 40, 'ItemDesc': 'UnitTest' } Key = '12345678901234567890123456789012' IV = '1234567890123456' expect_output = 'ff91c8aa01379e4de621a44e5f11f72e4d25bdb1a18242db6cef9ef07d80b0165e476fd1d9acaa53170272c82d122961e1a0700a7427cfa1cf90db7f6d6593bbc93102a4d4b9b66d9974c13c31a7ab4bba1d4e0790f0cbbbd7ad64c6d3c8012a601ceaa808bff70f94a8efa5a4f984b9d41304ffd879612177c622f75f4214...