[投票專題 Overview](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/HkkDB4G12) [投票專題 111上學期](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/not6914) [投票專題 111下學期](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/HJH2t28ho) [投票專題 112上學期](https://hackmd.io/@zRWCfXc1TOaCsnINOAPeCw/BJ6DDONkp) [系統整合實作的 Github organization](https://github.com/System-Integration-Implementation) [暫時使用google cloud來部屬](https://console.cloud.google.com/home/dashboard?hl=zh-tw&project=go-fido) --- # 0622 Update 全新分工: 1. 處理送app與google cloud互動 2. 處理token(送到firebase) 最新branch: UI-branch: 2023_0623_UI_CHU ## Outline 1. flutter接到GO project 2. 佈署GO到google cloud 3. android native研究 ### 佈署GO到google cloud 佈署的GO版本是能夠產生JWT的版本 Go project github: [github links](https://github.com/System-Integration-Implementation/JWT-Demo) 可以直接demo(using Google Cloud Shell) ### flutter接到GO project(誰有時間就先寫) // 先軟體模擬加密 flutter-Go API送request給google cloud -> 用寫在Go project的生物辨識認證 -> go project return JWT 有JWT之後 -> 送給firebase customSignIn - 主要功能(FIDO) 難點: - 不確定以現在的方式需要改多少比例的GO project以讓他成功被呼叫 - main function那邊(main需要留多少) - 呼叫function(因為目前demo的版本是用給定的user直接做出來 也就是作假解的意思) - 不確定原理 - 最主要是不確定是不是需要另行手動turn on server? - 還是單純部署上去就可以了?(像是firebase一樣) - 也不確定部署了之後是隨時都會開著server嗎? - 還是有rerquest時才會重新啟動? - 儲存key值 - 可能可以參考參考資料裡面的方式(使用PostgresDB) 總之現在進度: 成功部署到Google Cloud,但目前覺得需要再更改過go裡面的code才能動。 流程: 先盡量把流程圖裡面可能會使用到的function都生出來,之後再組裝。 - 可以成功的從app 送http request 給 server(在localhost測試), 但是實際收到後要做什麼,還未實作(call android native api)。 | 內容 | 圖示 | |:--------------------:|:--------------------------------------------------------------:| | Flutter Http request | ![](https://hackmd.io/_uploads/ByXuA94u3.png "title" =504x126) | | Go Server(localhost) | ![](https://hackmd.io/_uploads/Byi0gsE_h.png "title" =504x160) | - UI - 主要是參考之前找到的go example 將login 的版面配置進行調整。 ![](https://hackmd.io/_uploads/By-VPjWO2.gif "title" =216x456) - 改變版面配置。 | Public Polls | Private Polls | Create Polls | | -------------------------------------------------------------- | -------------------------------------------------------------- |:--------------------------------------------------------------:| | ![](https://hackmd.io/_uploads/rJ-VYoZun.png "title" =216x456) | ![](https://hackmd.io/_uploads/BJZVtobd3.png "title" =216x456) | ![](https://hackmd.io/_uploads/H1ZEKsbdn.png "title" =216x456) | Reference: 1. [Using Go as backend](https://blog.logrocket.com/why-use-go-backend-flutter/) 2. [Github using Flutter Web + Go BE + Postgres DB + NGINX + Docker](https://github.com/xajik/go_flutter) ### android native研究 目標: 希望直接call到安全晶片 關鍵字"硬體加解密", "硬體生成keypair", "安全晶片生成keypair", "android調用安全晶片" 還是沒有查到直接調用安全晶片的方式,幾乎查什麼都會帶我們到android developers的網站,看蠻多影片教學也都直接呼叫api。 問題: - 希望是用很常見的RSA、AES嗎,還是要自己想一種演算法? - 還是不太理解直接call安全晶片是什麼意思。 參考資料: [加解密影片教學](https://www.bing.com/videos/search?q=android+hardware+encryption&docid=603495587189435719&mid=7B21651C9119652189E67B21651C9119652189E6&view=detail&FORM=VIRE)(還有很多,但這個感覺最詳細) [Android Keystore official docs](https://developer.android.com/training/articles/keystore) [Android Trusty TEE official docs](https://source.android.com/docs/security/features/trusty) [Android Hardware-backed Keystore official docs](https://source.android.com/docs/security/features/keystore) [安全晶片wiki](https://zh.wikipedia.org/zh-tw/%E5%AE%89%E5%85%A8%E5%8A%A0%E5%AF%86%E5%8D%94%E8%99%95%E7%90%86%E5%99%A8) new keyword: "Trusted Execution Environment (TEE)" "Secure Element (SE)" 安全晶片 = "Secure Cryptoprocessor" or "security chip" ## 建議 1. 參考google cloud policy 2. 找找看Go 接收http 相應的package 3. 手機和server都會有各自要做的部分,而兩者之間是用http&API來處理。 4. 確保call的api,其中有硬體(ex. TEE?)的支援(產生key,儲存key,保存key)。 5. 如果知道如何使用硬體支援的方式管理的話,建議還是用現有的演算法。 6. 有定義好的生成key api,要確認是不是有用到硬體 7. 可查看看大家最常用最安全的方法 --- # 0704 Update JWT相關(驗證、更改GO project裡面的code) - 簡 前端(先trace閱讀資料的github) - 祝 後端(先trace閱讀資料的github&下次meeting時講google cloud policy) - 我 查資料 - 吳為主、簡幫忙 閱讀資料[Github using Flutter Web + Go BE + Postgres DB + NGINX + Docker](https://github.com/xajik/go_flutter) ## Outline ### JWT相關(驗證、更改GO project裡面的code) 主要是更改RS256.go。 - 以往的版本是把public/private key都寫死在code裡,因此產生的JWT token都一樣。 - 改完code之後的版本每次執行都能產生新的一組keypair並將public/private key分別寫進不同的file裡面,再讓code去讀取它們以進行JWT signing 有待更改的code: 目前JWT每次簽署的內容(claim)都一樣,看之後的需求進行更改 ref. [tutorial 1](https://www.systutorials.com/how-to-generate-rsa-private-and-public-key-pair-in-go-lang/#google_vignette) [stackoverflow 1](https://stackoverflow.com/questions/64104586/use-golang-to-get-rsa-key-the-same-way-openssl-genrsa) [stackoverflow 2](https://stackoverflow.com/questions/44230634/how-to-read-an-rsa-key-from-file) [medium tutorial](https://medium.com/@Raulgzm/export-import-pem-files-in-go-67614624adc7) ### Front-end research & implement - Front-end Goal: 目前架構是在**應用程式**,在點擊註冊/登入後調用手機內部的**驗證器**(authenticator, 比方說生物驗證等,然後產生公私鑰, 憑證...) 該憑證(or公鑰?)會傳送到 我們的**Token Server**(google cloud上,用來管理帳號的server) 依照Fido or webauthn(Server side?) 確認後,從該處取得jwt token 後,手機再用該token 登入firebase。 當下前端的目標是利用 webauthn-example-main repository(一個go repo,可以用來做webauthn登入)在localhost中運行,利用我們手機(emulator)進行一次webauthn[1] 現在的進度... - [x] - 能正確的送出 get,然後將localhost回傳的response轉成json 格式 - [ ] 根據json 格式內的資訊在android 端生成credential (進行中) - [ ] 傳送 http post ,將credential 傳回localhost。(未完成,但是只要前一步完成,這一步很快。) - Implement 有找到一個flutter package(local_auth),能做local的驗證,調用生物辨識。目前測試是跑的,但是還沒用它開啟驗證過。現階段還不確定該repo是否符合我們對驗證器的要求[2] 安裝後,需要升級kotlin 到1.7.10(還有其他要調整的,但是基本上拉下來跑之後,vscode flutter extension 會協助完成。) > Android Studio, FILE > SETTINGS > LANGUAGE AND FRAMEWORK > KOTLIN UPDATES > install 212-1.7.10-release-333-AS5457.46(Stable)[3] 另外,現在已經將別人report 中js的部分中,http的處理完成,但是要回傳的東西(按照原本的repo,是用browser去生成憑證作webauthn,但是換到我們這邊就是需要由手機做為authenticator來處理這部分的東西。[4] 有關這個package,目前是為了快速進度(之前找到的Android Fido2ClientAPI卡關中,所以繞過), 所以先暫時使用的,but尚未trace其code是否有用到硬體存儲金鑰,或者它是否是符合Fido。 不過,因為有另外一個package(webauthn)是基於它開發的,應該是微調就好 - Problems & Researches 我們的request送出去的時候,我們需要再額外做一些加密嗎,還是就是只靠https協定本身的保護就夠了? - What's next 盡快完成驗證的部分,如此才比較容易處理server之間的溝通狀況,以及challange response的東西。 雖然該repo中有提供前端,但因為它用的是仰賴browser做驗證,與我們的使用andorid api的需求較不符。 參考資料&備註: 1. 因為是要直接在app中,處理完再送出,而非透過enulator 中的chrome所以嚴格來說應該不算webauthn(? 2. 使用安全晶片或類似的方式安全存放金鑰...等,但跟據其說明,應該是沒有。除非android一律將手機金鑰的管理都使用安全晶片來管理,他多半也是用類似 3. [How to find out the latest version of Kotlin in Android Studio](https://stackoverflow.com/questions/53682098/how-to-find-out-the-latest-version-of-kotlin-in-android-studio) 4. [相關說明,投票專題 111下學期(CTAP)](/nVW37qBfQiKJsjqVrHP1iQ#CTAPClient-to-Authenticator-Protocol-%E7%A5%9D) ### Back-end research & implement - Implement [tutorial video starting at 5:11](https://youtu.be/q-MMVcqryk4?t=311) ![](https://hackmd.io/_uploads/S1UZ-AUFn.png) ![](https://hackmd.io/_uploads/B1eFZRLtn.png) ![](https://hackmd.io/_uploads/S1-0-AUYn.png) 並且教學影片裡面有code(可是我找很久沒有看到github連結) 可能使用到的API: [gcloud](https://pub.dev/packages/gcloud) 目前還是在模仿、摸索該怎麼把back-end的事情搞定(查到的資料偏零散,需要花時間測試正確性以及整理)。 還有依然在確定是不是google cloud的使用方式真的就跟firebase相同,不需要http(因為從上述官方教學影片那邊,看到firebase, google cloud混用的情形) reference: [dart official document for google cloud](https://dart.dev/server/google-cloud) - Problems & Researches 遇到問題了! 有人曾經在stackoverflow上面提問"是否可以run SQL在google cloud?",而我從下面的回應看到,其實並沒有辦法。因為google cloud是stateless,因此ACID沒有辦法被保證(主要是Isolation)。 而上次提及的github參考資料中有使用到postgresql,是由於他們的環境並不是google cloud。 目前想到的解法: 使用cloud-SQL(google cloud的其他產品) 這裡特別指的是[Cloud Datastore API](https://console.cloud.google.com/apis/library/datastore.googleapis.com?hl=zh-tw&project=go-fido),這個功能目前已經在google cloud端啟用;他使用的是NoSQL,不過應該花個一兩天摸一下語法,會下query應該就可以了;不過目前大致上看過document,還是覺得蠻像firestore的。 reference: [StackOverflow - run SQL with google cloud](https://stackoverflow.com/questions/57864518/is-it-possible-to-run-postgres-or-any-db-with-google-cloud-run) - What's next 下一步目前暫定要將http那邊的事情先測出一個結果來,看成果如何再看看要往哪邊走。先求能夠接到google cloud,其他關於SQL的部分就先不動。 SQL的部分需要決定schema(資料的primary key之類的),model就等http弄出成果之後再設計、討論。 ### Dive into security API 希望查詢一個安全晶片制式化的用法 要能夠給各家以及各型號的android手機使用 android官網資料: - [java.security.KeyPairGenerator](https://developer.android.com/reference/java/security/KeyPairGenerator?hl=en) - 這個只有軟體實作 - 但可以使用keystore system把鑰匙保存在硬體裡面 - [android keystore system](https://developer.android.com/training/articles/keystore) - 可以限制金鑰的使用時間以及何種情況下能使用,例如要求使用者透過身份驗證才能使用金鑰或將金鑰限為僅在某些加密模式下使用 - Key material can be bound to the secure hardware of the Android device, such as the Trusted Execution Environment (TEE) or Secure Element (SE). - Supported devices running Android 9 (API level 28) or higher can have a StrongBox Keymaster. StrongBox 是一個可以保護加密鑰匙的硬體,底層利用embedded Secure Elements(eSE)或on-SoC secure processing units (iSE)。 - When generating or importing keys using the KeyStore class, you indicate a preference for storing the key in the StrongBox Keymaster by passing true to the setIsStrongBoxBacked() method. - strongBox不行的話再採用TEE ref: [QR code製作](https://www.bing.com/videos/search?q=flutter+make+qrcode&docid=603542599902709885&mid=0A2C9C3234B5B041901B0A2C9C3234B5B041901B&view=detail&FORM=VIRE) [QR code教學](https://blog.flutterflow.io/qr-code-generator/) [flutter QR code官網](https://pub.dev/packages/qr_flutter) ## 建議 1. flask調查 2. 要怎麼改之前的後端 3. 前端繼續做 --- # 0714 Update ## Outline 1. Front-end 2. Flask Researches 3. How to modify our project(GCP cooperate with flask) 4. backend todo summary ### Front-end(祝、簡) Newest Branch: ProgressChu0711 可能會用到: [local_auth package](https://pub.dev/packages/local_auth/example) [local 測的server](https://github.com/NHAS/webauthn-example) [native code YT](https://www.youtube.com/watch?v=6UftAAKSuVs) [上學期查到的FIDO2AndroidAPI(native code)](https://developers.google.com/android/reference/com/google/android/gms/fido/fido2/Fido2ApiClient#isUserVerifyingPlatformAuthenticatorAvailable()) 這周有去看android官方[FIDO2 codelab](https://codelabs.developers.google.com/codelabs/fido2-for-android#0)是怎麼在原生端實作的FIDO2的,用android studio有把app跑起來,但目前有遇到一些問題正在處理中 另外,因為之前是往使用Credential Manager的方向走, 最初會選擇Credential 是因為在localhost用來測的server需要收到 credential,但是在前進過程中遇到問題,且方向走的有點歪,相較於Credential Manager,Fido2api顯然更符合需求,所以會轉去implement FIDO2api(還是卡關..)。 目前遭遇的問題: 1. Fido2android api demo使完全用java 和kotlin寫的,要轉到flutter的事後,中間的一些邏輯需要確認(api 要怎麼接入) 2. Fido2Api android api,在java 和 kotlin的使用法(document有寫,但是一直出問題,目前應該是因為不熟悉他們的基本概念,所以才一直出問題) 4. 查到的網路資料一下java一下kotlin, 有點亂。 ### Flask Researches(吳) 關鍵字: 架設web server API, python flask 會議重點: - google cloud - 要能產生jwt - 儲存keypair - 是一個token server - localhost跟google cloud溝通有難度 - 目標是要把字串跟gcp溝通 **flask網路教學:** 根目錄的情況: ![](https://hackmd.io/_uploads/S1xuZVjr92.png) ![](https://hackmd.io/_uploads/HkI7EjB53.png) 加上想要的路徑: ![](https://hackmd.io/_uploads/ryPo4sr52.png) ![](https://hackmd.io/_uploads/Bk4REir53.png) **實際操作postman:** postman可以讓我們測試http request。 遇到問題了,照著教學的程式碼執行,卻無法成功完成http request,仍然在找原因。 嘗試用了waitress的寫法還是沒有反應。 --> 已解決 實際測試print hello: ![](https://hackmd.io/_uploads/rksWXZA93.png) ![](https://hackmd.io/_uploads/Sk3QmWA92.png) 先測試是否能接收jason的input: ![](https://hackmd.io/_uploads/ByL2hSyj2.png) 把input加上20000之後回傳: ![](https://hackmd.io/_uploads/r1sVMIyo3.png) **應用到專題:** 測試API的工具可以使用Postman。 可以利用http request把keypair從前端用json格式傳給flask,進行完加密運算之後回傳token字串,也是用json格式傳回app。 ref: [flast入門指南](https://devs.tw/post/448) [flask網站架設影片](https://www.youtube.com/watch?v=UdRxvHVXTxA&list=PL-g0fdC5RMboN18JNTMCEfe8Ldk8C5pS-) [架設api](https://ithelp.ithome.com.tw/articles/10280422) [鐵人賽影片教學](https://ithelp.ithome.com.tw/articles/10251579) [鐵人賽 GCP部署機器學習API](https://ithelp.ithome.com.tw/articles/10252383) ### How to modify our project?(楊) **First of all**, get some articles about flask coorperating with GCP. I found TWO articles that helps. - First: 在 GCP 使用 Nginx 部署一個簡單的 Flask APP [link](https://blog.jihongo.com/posts/2020/05/31/deploy-a-simple-flask-app-on-gcp-with-nginx/) It's a step-by-step article. We'll follow those steps to build up our backends. Something worth to mention: - Web server, Nginx [link](https://medium.com/starbugs/web-server-nginx-2-bc41c6268646) In this link, I thought that this software is used as a tool to manage https-request. ![](https://hackmd.io/_uploads/r1BxgJyo3.png =90%x) - Certification using Cerbot [link](https://blog.miniasp.com/post/2021/02/11/Create-SSL-TLS-certificates-from-LetsEncrypt-using-Certbot) In my opinion, Cerbot is a website that helps us generating a https-links. It saids, after setting up a link on Cerbot, all we have to do is pointing this link to our APP on Nginx. - the rest is the same as the previos introduction. - Second: [GCP教學-Python] #1 部署第一個Python Flask API程式 [link](https://andy6804tw.github.io/2020/03/27/gcp-python-ep1/) It's a step-by-step article. We'll follow those steps to build up our backends. **However, this doesn't show how to deal with https-links.** So I my self thought that, this article might not be as hlepful as the above one. **Furthermore**, we stuck on the first step because of "creating a new VM need to pay" ![](https://hackmd.io/_uploads/ByoSz0A5h.png) I pay NT40 just to launch VM-API. ![](https://hackmd.io/_uploads/Synvu6Jo3.png =60%x) **Should we continue on this, or change the way to build a server?** **And then**, back to my topic. How to modify the current project? I think we can just test what the first article saids, i.e. I would open a new private GCP project. Next, translate go project to python code! ### Backend-TODO Summary 1. GCP problem 2. translate golang to python 3. testing reference: [flask tutorial](https://devs.tw/post/448) ## 建議 --- # 0803 Update ## Outline 1. frontend 2. golang to python 3. cloud shell連到外網 內外打通 ### Frontend 1. 實作的大方向 & 討論串 這篇[stackoverflow](https://stackoverflow.com/questions/61980197/how-to-implement-fido2-webauthn-for-android-and-ios)與[討論](https://www.appsloveworld.com/flutter/100/46/how-to-implement-fido2-webauthn-for-android-and-ios)有提供一些在flutter實作FIDO2的方向與建議,對我們有一些幫助。 [Google groups 討論串](https://groups.google.com/a/fidoalliance.org/g/fido-dev/c/ywAYStCCEuI/m/byeeQIgBGwAJ) 2. FIDO2 example code(都還沒跑) Flutter - [flutter plugin with example](https://github.com/mojaloop/contrib-fido2-flutter-lib) 2-1. 試跑結果:目前build成功但一打開App就跳error,因為還沒部署assetlink.json(需要自己的local domain name),能build的參考版本在[github organization](https://github.com/System-Integration-Implementation/FIDO2-Flutter-example) 2-2. 目前有把一些code搬進voting branch:`0724_DEBUG_SDFGSJ`裡,另外 某網友有更新這份example的Flutter, package, gradle版本=>[link](https://github.com/shafiqaiman96/contrib-fido2-flutter-lib)(還沒測試能不能build起來) - [Huawei example](https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-fido) with their API Android(`.kt` files only) - 某網友的[android demo](https://github.com/jedrivisser/fido2-android-api-demo)與其對應的[medium](https://jedri.medium.com/android-fido2-api-demo-422edd87f445)教學 - [Huawei example](https://developer.huawei.com/consumer/en/doc/development/Security-Examples/sample-code-0000001050158985) with their API 3. 其他API(目前尚未知其運作方式) 如果到時候Android FIDO2 API嚴重卡關的話,還有一些其他的API可以參考 [LoginID API](https://docs.loginid.io/Client-SDKs/Flutter/flutter#api-reference-) [reachfive API](https://developer.reachfive.com/sdk-android/8.1.2/guides/fido2.html) [Nitrokey API](https://www.nitrokey.com/products/android-fido2-sdk) 4. 關於在localhost上測試 ![](https://hackmd.io/_uploads/SJjCmqdj3.png) 上面的example中(除了Huawei,還沒看)都有將他們的APP部署到某個domain上,但目前我們尚未有自己的domain,因此在Flutter端實作FIDO2的時候只能嘗試先用localhost來代替。 相關文章: [stackoverflow](https://stackoverflow.com/questions/52870513/webauthn-development-on-localhost) [w3c/webauthn 討論串](https://github.com/w3c/webauthn/issues/1204) [google groups](https://groups.google.com/a/fidoalliance.org/g/fido-dev/c/H2eXb0Gs8rI) [strongkey/fido2 討論串](https://github.com/StrongKey/fido2/issues/29) [guide 1](https://webauthn-doc.spomky-labs.com/prerequisites/the-relying-party) [guide 2](https://developer.transmitsecurity.com/guides/webauthn/quick_start_sdk/) refs: [Fido2ApiClient](https://developers.google.com/android/reference/com/google/android/gms/fido/fido2/Fido2ApiClient) [Your First Android FIDO2 API](https://codelabs.developers.google.com/codelabs/fido2-for-android#0) ### Golang to Python https://www.codeconvert.ai/golang-to-python-converter 沒辦法直接轉,要想辦法讓postman可以得到input還有需要把output用json格式輸出。 沒有找到repo所以用chatgpt幫我寫一個可以生成keypair以及token的python程式。之後再改成flask版本還有結合一些之前RS256.GO的程式。 目前是用一個固定的private key來模仿一個使用者只有一個private key的情形,所以只要每次登入的claim是一樣的話,就會跑出相同的jwt。 ![](https://hackmd.io/_uploads/HyBKlC133.png) ![](https://hackmd.io/_uploads/SkNueCk3h.png) 未來目標: - email當作claim傳給python flask(看教學) - [Flutter Authentication Using Flask API](https://www.section.io/engineering-education/flutter-authentication-using-flask-api/),把所有驗證都寫在後端,如果要仿效就需要大改。 - finger print hash value 一些問題: 1. 使用者第一次登入後私鑰公鑰就會保持相同,所以往後的claim都需要相同才可以產生相同的jwt來驗證嗎? 2. claim裡面需要有那些東西才能確保安全?只有使用者名稱、email的話好像大家都可以登入進去,可能需要放一指紋或臉部辨識的資訊。 ref: [cmd問題](https://stackoverflow.com/questions/33198428/jwt-module-object-has-no-attribute-encode) [jwt](https://www.youtube.com/watch?v=7Q17ubqLfaM&t=2s) [Integrating Flask and Flutter apps](https://blog.logrocket.com/integrating-flask-flutter-apps/) [log in video](https://www.bing.com/videos/search?q=python+flask+and+flutter+login&&view=detail&mid=574915C44ECBB8F6744A574915C44ECBB8F6744A&&FORM=VRDGAR&ru=%2Fvideos%2Fsearch%3Fq%3Dpython%2Bflask%2Band%2Bflutter%2Blogin%26FORM%3DHDRSC6) ### Cloud Shell連到外網 內外打通 可以知道其實Cloud Shell是有防火牆的 https://stackoverflow.com/questions/57024031/gcp-open-firewall-only-to-cloud-shell 第四點 更新防火牆 https://www.cloudskillsboost.google/focuses/563?locale=zh_TW&parent=catalog 輸入{gcloud compute firewall-rules list},跳出畫面 ![](https://hackmd.io/_uploads/ryCOO0Jj2.png) 接著, ![](https://hackmd.io/_uploads/rJOh_A1i3.png) 看到document上面說,可能通訊失敗的原因 ![](https://hackmd.io/_uploads/BJPA_0yo3.png) 所以按照官方document,輸入{gcloud compute instances add-tags gcelab2 --tags http-server,https-server},出現error ![](https://hackmd.io/_uploads/SyHilHZi2.png) 看起來最根本的問題是沒有gcelab2這個東西? 於是跑去更新規則 ![](https://hackmd.io/_uploads/BJXWNzTjn.png) 找到一個github他寫了很多指令: [link](https://gist.github.com/luckylittle/e0515da9d9db3003fcb551767e501993) 使用以下這條指令: {gcloud compute firewall-rules create default-allow-http --direction=INGRESS --priority=1000 --network=default --action=ALLOW --rules=tcp:80 --source-ranges=0.0.0.0/0 --target-tags=http-server} ![](https://hackmd.io/_uploads/ry518zajh.png) 也就是說其實現在已經開好firewall了,那麼照理來說nginx上面的服務要可以動才是 ![](https://hackmd.io/_uploads/BkyKUfpoh.png) 另個嘗試,在那份參考資料裡面,我看到了這個 "Create a firewall rule to allow external traffic to the VM instances":{gcloud compute firewall-rules create www-firewall-network-lb --target-tags network-lb-tag --allow tcp:80} 再次更新,於是下定決心弄了一個GCP的VM(知道有試用期間的折扣125美,我沒有選一些比較高規格的配備,所以還行) {DEMO!} SSH、防火牆問題得到解決,因為有在VM那邊把http, https功能打勾 [再貼一次步驟](https://yanwei-liu.medium.com/google-cloud%E4%BD%BF%E7%94%A8%E7%AD%86%E8%A8%98-%E4%B8%80-%E4%BD%BF%E7%94%A8compute-engine%E9%83%A8%E7%BD%B2python%E7%A8%8B%E5%BC%8F-432c4794a73e) ## 建議 測試server的方法 1. [ngrok](https://ithelp.ithome.com.tw/articles/10197345) 2. open shell & type this: "python3 -m http.server" --- # 0817 Update ## Outline 1. frontend 2. python code 3. deploy on GCP ### frontend(祝、簡) 部署assetlink.json的方法: 1. [medium](https://medium.com/androiddevelopers/android-app-links-deploy-assetlinks-json-in-minutes-d7082dffcac) 按照裡面的教學在[sdfgsj.github.io](https://sdfgsj.github.io/.well-known/assetlinks.json)上部署assetlinks.json。 在部署時遇到的問題與stackoverflow的解法: [1](https://stackoverflow.com/questions/48541106/android-app-links-with-github-pages), [2](https://stackoverflow.com/questions/30443014/how-to-stop-redirecting-to-custom-domain) 2. [flutter docs](https://docs.flutter.dev/cookbook/navigation/set-up-app-links) 按照裡面的步驟建立一個測試用的APP來檢查assetlinks.json是否部署成功,結果為assetlinks.json有成功部署 最後也有按照[android developer](https://developer.android.com/training/app-links/verify-android-applinks)裡提供的API檢查assetlinks.json有沒有正確部署,測出來沒有問題。 ref:關於測試assetlinks.json的[stackoverflow](https://stackoverflow.com/questions/35518429/app-links-intent-filters-in-assetlinks-json-not-working-on-android) 生成SHA-256 fingerprint的指令: 1. keytool ![](https://hackmd.io/_uploads/HJWaMr763.png) 執行指令時會要求輸入密碼,而這篇[stackoverflow](https://stackoverflow.com/questions/16891182/keytool-error-keystore-was-tampered-with-or-password-was-incorrect)有提到輸入預設密碼即可(如果當初沒特別設定的話) 2. gradlew ![](https://hackmd.io/_uploads/SJP17HmT3.png) 要先切到project的android folder且確定系統環境變數中有JAVA_HOME才能使用 ref: [medium](https://medium.com/@MatchaLatt3/finding-sha1-and-sha-256-key-for-flutter-app-in-android-studio-on-windows-e24cc4d76328) 這份[Google docs](https://developers.google.com/android/guides/client-auth)都有提及以上生成SHA-256的兩種方法 ### python code(吳) [Flutter Authentication Using Flask API](https://www.section.io/engineering-education/flutter-authentication-using-flask-api/) 使用reference project的原因: - 了解flask跟flutter互動 - 包含login, register,可以真正拆成前後端,安全性提升。 - 測試成功則剩下處理key pair問題。 要注意的是,這份project的作者只有在localhost測試,使用postgresDB,因此在deploy到GCP的過程可能有些問題。 ![](https://hackmd.io/_uploads/r1xO3IyT3.png) 第一次嘗試有遇到版本問題,但後來改完環境設定的一些參數之後就可以成功了。 可以正常把localhost跑出來 ![](https://hackmd.io/_uploads/BkN7Iaea3.png) 什麼都沒有改的情況會出現error code 503 代表the server is not ready to handle the request ![](https://hackmd.io/_uploads/H15gJVN63.png) 有在flutter更改的地方 ![](https://hackmd.io/_uploads/rJN_LTeah.png) 變成 ![](https://hackmd.io/_uploads/B1WFUax6h.png) 但還是沒辦法成功註冊 ![](https://hackmd.io/_uploads/rkPvcaxph.png) 這目前是跑在虛擬機上面才出現的情況,stackoverflow建議跑在實體手機試試看 跑在實體手機上也出現一樣的問題。 問題或許出在postgresdb那邊: ![](https://hackmd.io/_uploads/SJhFyEV63.png) 應該大致上剩下postgresDB那邊要搞定 就會看的到東西了(這份程式碼是用Python library SQLalchemy搭配postgresql來寫的) 解決方法: - 查SQLalchemy相關的影片 - 看鐵人賽文章 - 找另一份flutter搭配SQLalchemy的repo 更改過的檔案放在github協作那邊 照理來說載下來就可以直接使用了,但要記得flutter pub get **注意! pip install requirement.txt在楊瑞凱電腦跑是載不出東西的(不確定其他人怎麼樣)!** reference1 -> backend reference2 -> frontend 我們從這份project中學到 - 前端跟我們目前app架構、功能差不多 - 後端如何跟SQL互動 ### deploy on GCP(楊) deploy到GCP有嘗試了 但有點問題 可以透過瀏覽器access linux伺服器,如圖 ![](https://hackmd.io/_uploads/HkB1x5m6n.png) 而他在ssh連線之後(輸入{gcloud compute ssh --zone "asia-east1-b" "fido1" --project "go-fido"}),會發現我們沒有public/private key,而沒有這個公私鑰對,pip指令是沒辦法生出來的(不確定是無法確定有無pip指令,還是這個VM沒有)。從ls指令來看,會發現遠端那邊整個都是空的,沒有檔案、沒有資料夾。 ![](https://hackmd.io/_uploads/B1SPlq7T3.png) 我找到了一篇文章,裡面使用了{scp --recurse}來複製local端的檔案過去,詳細要到官方的[gcloud compute scp recurse指令](https://cloud.google.com/sdk/gcloud/reference/compute/scp),但我看到的資料是舊版的,因此指令無法照抄(command語法似乎最近有更新) 小結論: 要先知道公私鑰那邊要怎麼設定,才有所謂權限去處理python相關的問題,也才能夠從本地端複製檔案過去。 [裡面指令用不了的reference(他的指令跟document不一樣)](https://www.section.io/engineering-education/deploy-flask-to-gce/) 預計先弄明白他的公私鑰對到底在幹嘛,再進行測試。 ## 建議 調查assetlinks.json的用意(為何要有這個東西?跟誰互動?) 能不能將assetlinks.json部署在localhost? 尋求python -m http-server解(類似file server) postgres pgadmin搜尋 ![](https://hackmd.io/_uploads/r1ZxL6Vah.png) --- # 0831 Update ## Outline 1. frontend 解決"The incoming request cannot be validated" Error,看能否使指紋驗證器跳出來。 調查assetlinks.json的用意(為何要有這個東西?跟誰互動?) 能不能將assetlinks.json部署在localhost?尋求python -m http-server解(類似file server) 2. backend postgresSQL搞定 整個可以動 再考慮更改 GCP繼續更新 熟悉功能 ### frontend 1. 解決register, sign的bug - register 目前查到資料說,Webauthn(FIDO2)的協定中,要求RPDemain(Relying Party 的 Domain Name)和RPID要是一致的 eg. RPDomain = https://login.example.com:1337 RPID:login.example.com 或 example.com 另外一定要使用Https 衍伸問題: 因為現在是在localhost中測試,但在Emulator中,必須從10.0.2.2存取,而非localhost或127.0.0.1。 =>先將assetlink實際deploy,另外虛擬機影響不大,仍可使用。 [Android FIDO2 throwing vague errors](https://stackoverflow.com/questions/68639655/android-fido2-throwing-vague-errors) [WebAuthn Authentication Official Doc](https://www.w3.org/TR/webauthn-2/#relying-party-identifier) 結果最後發現是assetlinks.json的`"package_name"`錯誤。 - sign 在trace code的過程中發現`userHandle`的值一直是null,導致程式執行不到之後的code,後來查了[Webauthn Spec](https://www.w3.org/TR/webauthn-2/#dom-authenticatorassertionresponse-userhandle)中關於`userHandle`的資料,發現它是nullable,因此將型別改成nullable後sign就可以正常運作了 ![](https://hackmd.io/_uploads/SyEFj9rp3.png) ![](https://hackmd.io/_uploads/H19cjcrpn.png) 有把能跑的code放在Github organization 2. 調查assetlinks.json的用意(為何要有這個東西?跟誰互動?) 在這份[repo](https://github.com/google/digitalassetlinks/blob/master/well-known/details.md)中有詳細的Asset links Spec。 assetlinks不只可以將1個domain連接到1個app,它也可以做到: (1)多個domain連接到1個app。 (2)1個domain連接到多個app,ex.當你的網站上有許多的功能,而且它們皆需導向到不同App的解法:[stackoverflow](https://stackoverflow.com/questions/48056006/how-to-create-assetlinks-json-when-website-is-handled-by-multiple-apps)。 這篇[stackoverflow](https://stackoverflow.com/questions/44209477/what-is-the-assetlinks-json-file-for-when-using-android-deep-links)有說到assetlinks可以讓website跟app之間的互動更加方便快速。以往沒有assetlinks時,developer、website owner之間需要做一些繁瑣的事前設定,但是當你把assetlink部署到某個domain上(代表你擁有那個domain的權限),就可以省去事前的準備。 ![](https://hackmd.io/_uploads/B1KtCwXC3.png) 這篇[Google docs](https://developers.google.com/digital-asset-links/v1/relation-strings)提到上圖的權限就那2種(如果情況有需要甚至還可以自訂string,但docs沒說怎麼自訂) ref: stackoverflow: [1](https://stackoverflow.com/questions/62066954/is-assetlinks-json-file-hosting-mandatory-for-fido), [2](https://stackoverflow.com/questions/62035232/do-we-really-need-to-host-assetlinks-json-file-for-an-android-app) [Google groups](https://groups.google.com/a/fidoalliance.org/g/fido-dev/c/gq9oo1I942A?pli=1) 關於app links的[android developer docs](https://developer.android.com/training/app-links) 關於Digital Asset Links的[Google docs](https://developers.google.com/digital-asset-links/v1/getting-started) 3. assetlinks.json能不能部署在localhost? 利用`python -m http.server`是可以從網頁上看到json的內容,但是用Google API測試assetlinks.json有沒有正確部署時卻產生了錯誤。 猜測原因為localhost不是一個public domain,因此無法被Google API訪問到。 但是用ngrok的話就可以被Google API訪問到,因此可以用ngrok將assetlinks.json部署到localhost 4. 其他參考資料 關於Android模擬器localhost的[stackoverflow](https://stackoverflow.com/questions/39948595/fetch-apican-not-get-data-from-localhost)與[Android docs](https://developer.android.com/studio/run/emulator-networking) 用實體手機連線到PC上的localhost的stackoverflow: [1](https://stackoverflow.com/questions/4779963/how-can-i-access-my-localhost-from-my-android-device), [2](https://stackoverflow.com/questions/9887621/accessing-localhost-of-pc-from-usb-connected-android-mobile-device/17603378#17603378), [3](https://stackoverflow.com/questions/68919285/how-to-solve-the-problem-of-android-app-link-verification-failed) ### backend-postgreSQL(上次) 試著讓flutter可以取得table某的欄位的值 --> [官網教學](https://pub.dev/packages/postgres) 似乎跟上次trace code的方法不太一樣 ![](https://hackmd.io/_uploads/SJhFyEV63.png) 官網說明 ```c var connection = PostgreSQLConnection("localhost", 5432, "dart_test", username: "dart", password: "dart"); await connection.open(); ``` 觀念錯誤,一直往flutter跟psql的實作方向找,應該要往python flask跟psql的方向找。 目前想法: - 直接讓上一次的範例程式成功跑起來似乎有困難,因為不知道DB的內容長怎樣。 - 自己實作看看簡單的結構 **PostgreSQL Windows version:** ref: [postgrSQL youtube](https://www.youtube.com/watch?v=XQ_6G0iCyMQ&list=PLwvrYc43l1MxAEOI_KwGe8l42uJxMoKeS) 去官網下載postgreSQL之後成功的畫面如下 ![](https://hackmd.io/_uploads/ByJLI0IA2.png) 試著創建新的資料庫 ```clike CREATE DATABASE test; ``` ![](https://hackmd.io/_uploads/HJTQ8AUC3.png =200%x) 卡住了,密碼不知道為什麼錯誤(但這似乎不影響,用SQL shell就可以) ![](https://hackmd.io/_uploads/r12xsJr02.png) 可以試的方向 1. [調整設定](https://stackoverflow.com/questions/74481804/psql-error-connection-to-server-at-localhost-1-port-5432-failed-fatal) 2. [開一個新的DB](https://stackoverflow.com/questions/30641512/create-database-from-command-line) [connect to postgreSQL](https://www.javatpoint.com/connect-to-a-postgresql-database-server) [python with postgresQL](https://www.1ju.org/postgresql/postgresql-python) [sql shell 指令](https://commandprompt.com/education/postgresql-basic-psql-commands/#:~:text=Here%20are%20some%20of%20the%20most%20frequently%20used%2C,8%20List%20All%20Schemas%3A%20%E2%80%9C%20%5Cdn%20%E2%80%9D.%20%E6%9B%B4%E5%A4%9A%E9%A0%85%E7%9B%AE) 在sql shell建立table ![](https://hackmd.io/_uploads/S1U3NCIR3.png =90%x) 透過python建立table ![](https://hackmd.io/_uploads/ByTUtGD0h.png =90%x) ![](https://hackmd.io/_uploads/BkRDtMw02.png =90%x) 加入資料 ![](https://hackmd.io/_uploads/rJnbQaVJa.png =90%x) ![](https://hackmd.io/_uploads/HkKmX6Vya.png =90%x) 取得資料 ![](https://hackmd.io/_uploads/S1BKN6V1a.png =90%x) ![](https://hackmd.io/_uploads/rJ-hNpNkT.png =50%x) 問題: - 不太了解為什麼上面的程式在沒有開啟sql shell的時候也可以成功跑起來,伺服器關掉竟然也成功? - 直接在python flask寫SQL語言的方法是正確的嗎?還是通常會引入library讓程式看起來比較像python的風格? 目標: - flutter app透過http request之後連到python flask,再透過python flask拿到postgresql的資料並傳回前端,印出取得的資料。 - 先用postman測試可不可以用python flask取得資料。 - 成功之後查看看怎麼讓flutter連到python flask(如何換URI)。 - ![](https://hackmd.io/_uploads/By54ubwRn.png) flask測試: 寫了一個取得全部資料的檔案,以及一個取得某一行資料的檔案。 - 取得所有資料 ![](https://hackmd.io/_uploads/B1bOhqdyT.png =40%x) - 取得第三行的資料 ![](https://hackmd.io/_uploads/BkWv2iuJ6.png =40%x) - 可以透過打出數字來取得某一行的資料(不確定這樣是不是一個好的方式) ![](https://hackmd.io/_uploads/Sy__RcY1T.png) ![](https://hackmd.io/_uploads/B1oVsnOy6.png =40%x) 結論: 如果可以串接前後端跟資料庫之後,就可以把之前寫過的key pair檔案加進來。 ------ ### backend-CloudSQL 動機: 既然gcloud支援postgressql,那不然可以直接嘗試cloud sql? Recall 整體後端需要的功能 1. DB in order to store user info 2. SQL connect to server, specifically, exchange data between DB and server 3. server connect to flutter 一、 google cloud sql支援在cloud shell使用postgresql(也就是cloud SQL支援postgresql,到時候只要在cloud SQL那邊寫postgresql就好) 使用這個command把cloud SQL功能打開 ```code= gcloud services enable sqladmin.googleapis.com ``` ![](https://hackmd.io/_uploads/H14Yqx8Ch.png =60%x)![](https://hackmd.io/_uploads/SkJpcg8Rh.png =40%x) ![](https://hackmd.io/_uploads/Hk6oneUAh.png) 目前還沒有create東西 ![](https://hackmd.io/_uploads/BykF6eUC2.png) ![](https://hackmd.io/_uploads/rJaqTlIC2.png =50%x)![](https://hackmd.io/_uploads/SkLjalURn.png =50%x) 在**網路連線設定**中可以看到兩個部分(另一個地方沒截到) - SSL/TSL相關介紹:[介紹與比較](https://www.nss.com.tw/ssl-introduction) 簡單來說就是一種使用加密的協定來防止資料外洩 - AuthProxy What is AuthProxy? ![](https://hackmd.io/_uploads/S1_QSgP0n.png) > AuthProxy is a plugin that takes care of the Traffic Server end of authorizing a request and delegates the authorization decision to an external HTTP service. reference: [AuthProxy Plugin](https://docs.trafficserver.apache.org/en/9.0.x/admin-guide/plugins/authproxy.en.html) 因此,其實我們有必要把這個功能打開使用! [官方教學](https://cloud.google.com/sql/docs/postgres/connect-auth-proxy)上面寫到一點更重要的,authproxy可以使用credential驗證使用者帳號 ![](https://hackmd.io/_uploads/rkoGbgv03.png) 二、 怎麼讓SQL跟VM互動,找到了在stackoverflow的[文章](https://stackoverflow.com/questions/27573161/is-it-possible-to-connect-to-google-cloud-sql-from-a-google-managed-vm),他提供了步驟與方法;可以知道基本上大家都是照著官網的指引就可以讓他們互動。 還有找到另一篇關於Python打開SQL server connection(不確定會不會使用到) [官方範例(含有程式碼)](https://cloud.google.com/sql/docs/sqlserver/samples/cloud-sql-sqlserver-sqlalchemy-connect-connector) 需要的東西已經大致上調查完畢,所以做了一個list來想一下現階段需要做甚麼 - [ ] 搞清楚在SQL存甚麼資料 - [ ] 設計schema - [ ] 測試http-request(能不能與VM互動、傳資料到SQL) - [ ] 藉由加入assetlinks、與SQL互動和JWT轉換來更改別人的flask project - [ ] 檢查credential和signature正確性 - [ ] 測試http-request(能不能傳回JWT到flutter) 提問與想法 我們該怎麼更改flask project,讓他符合我們的需求? 1. 原本flask的部分 我們其實並不需要在GCP那邊儲存票數,因此flask要處理的SQL只剩下使用者資訊(user name, key pair...etc)。 如此還會出現另一個問題,也就是說在firebase那邊也需要多記一次登入資訊;那這樣子多此一舉會是最佳解嗎? 2. assetlinks 同前面報告的部分,assetlinks用來實現跨App之間的跳轉(FIDO);因此也需要傳上去後端。 assetlinks相關問題,不確定是不是只要單純上傳到VM,就可以動?還是需要在後端另外多寫一點東西來幫忙? 我的猜測: 目前聽起來應該是不需要;因為抓取跟執行的部分不需要在server端實作 3. JWT JWT的部分其實已經寫好了,目前需要處理的是怎麼接上去(在python內呼叫、http-request的問題) 包成function,在確認登入身分之後,直接function call,並且用http送回前端 4. schema設計 想知道該怎麼設計schema會比較合適? 目前在firebase裡面儲存的使用者資訊有: username, uid, email 那大致上會加上pubkey來代表進行驗證的key pair ![](https://hackmd.io/_uploads/H1jErIOJa.png) (reference:[webauthn trace code description](https://blog.techbridge.cc/2019/08/17/webauthn-intro/)) 這樣就夠了嗎? 或是要怎麼樣可以比較清楚知道我們現在需要存甚麼資料? 閱讀: [postgresSQL tutorial](https://docs.postgresql.tw/tutorial/getting-started) [sqlalchemy-stackoverflow](https://stackoverflow.com/questions/62568478/how-to-set-sqlalchemy-database-uri) [google cloud sql for postgresSQL](https://cloud.google.com/sql/docs/postgres/) ## 建議 1. assetlinks不用更改 丟著就好 2. schema ---