Jex’s Note

Backend

安全性

  • SSL 憑證及加密傳送 (HTTPS)
  • 資料再以 private key 做 AES CBC 方式加密
  • 對某些重要的值使用 private key 以 sha1 產生 signature 參數做驗證
  • token & Access-Control-Allow-Origin (CSRF)
  • htmlspecialchars (XSS)
  • SQL injection

HTTPS

加密所有 request 及 response 資料, 包含 URL, 如果你使用 Http Proxy, 它只知道目標 server 的 domain, 不會知道 url path

意思是如果攔截到 https 封包只會看到 IP 跟 domain

設計 RESTful API 注意地方

避免使用 cookie, 因違反無狀態協議, 如果只用來記錄 client 資料不維護狀態, 那麼還是可以使用

session 則完全違反 REST 的無狀態性

解決方式是 client 登入後產生 token, 再從 url 帶 token 過來

驗證身份方法1. 永遠使用 ssl, 就不用每次讓用戶對每次請求簽名

驗證身份方法2. server 將 token 加/解密對應到 session ID, application server 再用 session ID 取得用戶資料判斷權限

增加網站效能

server

  • ELB (HA), auto-scaling
  • nginx 取代 apache

後端

  • background job
  • cache 靜態頁面
  • memcache / redis

前端

  • js/css minify & combine
  • 圖片用另一個 domain 避免 browser 一次只能發幾個 request 的限制, 也避免帶到不必要的 cookie
  • 一開始先載 lazy_image, 放真正圖片連結在 data-original= 最後再用 js 將 load 正確圖片

mysql

  • 使用 in 代替 or
  • slow query
  • Mysql set index
  • master - slave

Http

GET

GET 是我們最常使用也是最簡單的,它帶資料的方式就是把 query string 放在網址後面 :

example.com?f1=v1&f2=v2

GET 沒有 Body, 整個 Http 封包會像這樣 :

GET /api/test?f1=v1&f2=v2 HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 0f99b8e9-0322-952e-a67c-76b498c51903

POST form

當要背景傳送資料時要使用 POST,也就是我們常在用的表單,它的實現原理是在 Header 加上 Content-Type: application/x-www-form-urlencoded

而 Body 就是 query string :

f1=v1&f2=v2

整個 Http 封包會像這樣 :

POST /api/test?f1=f1&f2=v2 HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: 3f036f1b-dfec-1269-41b7-bbf6781cbac4

f1=v1&f2=v2

POST 可同時支援 GET 及 POST 的參數

POST with file

如果要傳送檔案,就不是用原本的 Content-Type: application/x-www-form-urlencoded,要改用 Content-Type: multipart/form-data

雖然說 Content-Type 使用後者,但仍然一樣可以傳送 form data

你的 params 會被拆解成一塊一塊的,整個 Http 封包會像這樣 :

POST /api/test/ HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: b953aac1-b8d5-f1e4-36ac-2672b3a028fc

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="image"; filename=""
Content-Type:

data:application/octet-stream;base64,/9j/4AAQSkZJRgABAQEASABIAA....
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="f1"

v1
------WebKitFormBoundary7MA4YWxkTrZu0gW--

關於 App

  • 手機裡的 App 會有個 UUID,不同的 App UUID 也會不一樣,即使同 App
  • App 重新安裝 UUID 會是新的,或者 UUID 好像也有過期時間 (e.g. 180 天)
  • 當 app 下載完 UUID 就會像 e.g. APN 註冊,所以 Push Notification 才知道要推給誰
  • app 可以自已選擇要不要濾掉 notification,也就是其實發送成功但忽略它
  • Android 的 GCM 沒有分環境,都是用 Production; APN 有分環境有分 Sandbox 及 Production

Storage

  • 手機本身有兩個儲存的方式,一個是 sqlite,另一個是 local storage
  • sqlite 是一個檔案,所以讀寫要開檔跟關檔
  • local storage 是 key-value 型態,直接用就可以了

Notification Title

  • 如果 app 在前景 android 可以攔截, 並且指定要給的 title, 如果 app 在背景會由系統自行判斷, 如果 notification json format 有 title 的話會使用 title 的值當 notification title

app 與 server 溝通的幾種方式

  1. 原本的 silent push notification (APN/GCM)
  2. websocket (app 也能用 websocket)
  3. 使用主流的 library/sdk 來幫忙 e.g. google firebase / aws contigo
  4. mqtt, ampq, etc. messaging protocal
  5. AWS AppSync 可讓您輕鬆地建立協作式應用程式,以即時更新共享資料。您只要用簡易程式碼陳述式指定應用程式的資料,AWS AppSync 就會管理即時更新應用程式資料的所有必要作業。此外,AWS AppSync 還會在離線使用者重新連上網路時立刻更新相關資料。它只會擷取必要的資料,藉此降低訊息流量並提升應用程式效能和電池壽命。

Distributed System (Sub/Pub)

  • MQTT
    • 主要用在 IoT
    • MQTT is a lightweight protocol working only with a broker in the middle with no concept of queue (it can store messages when a client is offline using the “clean session” feature). It has another feature over AMQP like the “will” testment. It supports only pub/sub and have no metadata in the messages.
    • mqtt over websocket, 讓 app/website 使用 websocket 連接 server, 利用 mqtt 做 sub/pub 功能
  • AMQP
    • AMQP is more oriented to messaging than MQTT. It was created by JP Morgan for business transactions.
  • MQTT vs AMQP
    • The first big difference with MQTT is that AMQP 1.0 is a peer-to-peer protocol : you can use it between two peers, no need for a broker in the middle. Of course it’s used for communication with broker providing store-and-forward mechanism. You can use it for request/reply pattern and for pub/sub.
  • kafka
    • 主要用在 log 收集
    • 每個 topic 劃分多個 partition
    • 內部實現不用 cache, 都存在硬碟
    • data 會批量壓縮傳送
    • kafka 會將 data 儲存下來, 訂購的可以自已控制 pull
  • Redis pub/sub

Log 系統

  1. CloudWatch Log agent 丟到 cloudwatch 或是直接用 Kinesis agent 丟到 Kinesis Streams
    • 上面任一方法 -> Kinesis Firehose (log) -> s3
    • 上面任一方法 -> Kinesis Firehose (log) -> Kinesis Analytics (SQL query) -> Firehose (result) -> s3
  2. ELK stack : ElasticSearch(搜尋引擎) + Kibana(顯示圖表/結果) + Logstash (收集 log, 也可用 filebeat/FluentD)
  3. Telegraf / Collectd + InfluxDB + Grafana 易安裝
  4. Fluentd + Prometheus + Grafana

2,3,4 都要自已架, 成本也高

ref: * https://rickhw.github.io/2017/03/02/AWS/Study-Notes-CloudWatch/

DST 時間 (日光節約時間)

某些國家會調整當地時間以符合日光節約時間,當程式在處理不同國家時間時就要注意了,將時間轉成 dst 存下來, 可以使用別人寫好的第三方來轉,下次取時再將 utc 轉成 dst 撈出來。

如何避免 response header X-Content-Type-Options: nosniff

如果 MIME 類型與 URL 的 MIME 類型不匹配,則不允許讀取該檔案

我還不是很了解這個實際判斷的方式是什麼, 但我加上 cookie 後, 就可以下載 google drive 的檔案了

CORS

chrome 會先發一個 method: OPTIONS 的 request 測試是否通, 但不會幫你加上 body 及 header

Proxy vs Reverse Proxy

Proxy 後面的 server 有直接對外

Reverse Proxy 後面 server 沒有直接對外

編碼

輸出 emoji / unicode character / 表情符號

"\xF0\x9F\x98\x81"     // 用 Bytes (UTF-8 encoding) 輸出笑臉
"\uD83D\uDE01"         // 用 Unicode (UTF-16 encoding) 輸出笑臉
"\U0001F601"           // 用 Unicode (UTF-32 encoding) 輸出笑臉

utf-8 與 unicode 的不同

  • UTF-8 is an encoding
  • Unicode is a character set

以下是 string 用 unicode 存到硬碟到取出解碼的過程

1) 將文字轉成 unicode

A character set is a list of characters with unique numbers (these numbers are sometimes referred to as “code points”).

For example, in the Unicode character set, the number for A is 41.

2) 將 unicode 用 utf-8 編碼成 binary

An encoding on the other hand, is an algorithm that translates a list of numbers to binary so it can be stored on disk.

For example UTF-8 would translate the number sequence 1, 2, 3, 4 like this: 00000001 00000010 00000011 00000100

Our data is now translated into binary and can now be saved to disk.

3) 將 binary 用 utf-8 解碼成 unicode

Say an application reads the following from the disk: 1101000 1100101 1101100 1101100 1101111

The app knows this data represent a Unicode string encoded with UTF-8 and must show this as text to the user. First step, is to convert the binary data to numbers. The app uses the UTF-8 algorithm to decode the data. In this case, the decoder returns this: 104 101 108 108 111

4) 將 unicode 轉回成 string

Since the app knows this is a Unicode string, it can assume each number represents a character. We use the Unicode character set to translate each number to a corresponding character. The resulting string is “hello”.

Comments