Try   HackMD

Week3 進度報告

Backend: 2021.05.21 Jeff

tags: bcrypt JWT Google Vision API

上週任務

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Bcrypt

一個 Node.js Library。能協助使用者密碼作雜湊。

  • Bcrypt 能幹嗎?

    • 使用時機
      • 當資料庫被盜,密碼不會被看光光
        • e.g.
          • Image Not Showing Possible Reasons
            • The image file may be corrupted
            • The server hosting the image is unavailable
            • The image path is incorrect
            • The image format is not supported
            Learn More →
            • 紅色匡起來,密碼是明文
            • 綠色匡起來,密碼已雜湊 -> 密碼經過雜湊(就算是資料庫管理者也不知道密碼)
  • Bcrypt 原理?

    • Bcrypt 其實一個密碼雜湊函數(單向雜湊 => 不可逆)。

    • 組成圖示 => 輸出為 60 個字串(固定)

      • Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More →
        reference link

      • Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More →
        reference link

    • 雜湊流程:

      • Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More →
      • 強度比較:
        • 明文 < 編碼 < 加密 < 雜湊 < 加鹽雜湊 < 加鹽 Bcrypt 雜湊(慢雜湊演算法) reference link
    • Cost factor = rounds = work factor => 若 rounds = 10 代表 雜湊

      210 rounds。數字越大,代表需要的計算時間成本更高,破解難度更大。

      和 MD5 一起來比較的話,如果使用值為12的 work factor 的話,如果加密 “cool” 的話,bcrypt 需要0.3秒,而 MD5 只需要一微秒(百萬分之一秒)。也就是說,前面我們說的那個只需要40秒就可以窮舉完所有的可能的 MD5 編碼的密碼的演算法,在使用 bcrypt 下,需要12年。

      reference link

  • 在 backend 的實作

    • import module
      • ​​​​​​​​​​const { hashSync, genSaltSync } = require('bcrypt');
    • 時機在 backend 上的 code
      • Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More →

JWT

  • JWT 是什麼?

    用於在雙方之間安全地將訊息作為 JSON 物件傳輸

  • JWT 能幹嗎?

    • 優點:
      • 簡潔(compact) -> 體積非常的小,可放在 URL 、 POST 參數或 HTTP Header 內發送請求,體積小意味著傳輸速度快
        Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More →
      • 自包含(self-contained) -> payload 裡面就有所需要的資訊,不需要再重新 query database 的資料。
    • 使用時機:
      • 授權 -> Client 帶著 JWT 而有相對應的資源。
      • 訊息交換 -> 因為可以透過公/私鑰做簽章,可以知道是誰發送的 JWT。也可以驗證內容是否遭到竄改。 reference link
  • JWT 驗證流程

    • Login 階段(前提:資料庫已經有使用者帳號、密碼)
      Created with Raphaël 2.2.0ClientClientAuth ServiceAuth ServiceUser Service(MySQL)User Service(MySQL)1. Login with username and password2. Get user info3. Reply4. Authenticate & generate token5. Reply result6. Reply JWT if login valid
    • 使用服務階段
      Created with Raphaël 2.2.0ClientClientAuth ServiceAuth ServiceUser ServiceUser Service1. Use suggesting system with JWT2. Verify JWT3. Open the suggesting system page4. Reply5. Reply result6. Reply result
      reference link
  • JWT 原理

    • 組成圖示

      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More →

      • Header
      • Payload
      • Signature
    • 驗證流程

      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More →

  • 在 backend 的實作

    • Login 階段
      • Image Not Showing Possible Reasons
        • The image file may be corrupted
        • The server hosting the image is unavailable
        • The image path is incorrect
        • The image format is not supported
        Learn More →
      • 四種狀況:
        • 藍色匡起來(無使用者名稱或錯誤的事件)
          • 沒背綠色框框的程式碼 -> MySQL 的錯誤處理
          • 綠色框框的程式碼 -> 無效的使用者名稱錯誤處理
        • 紅色匡起來(密碼正確或錯誤的事件)
          • 綠色框框的程式碼 -> 獲得 JWT (正確)
          • 沒背綠色框框的程式碼 -> 輸入錯誤密碼的錯誤處理
    • 使用服務階段
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More →
  • 使用 Postman 測試小技巧

    • Authoriaztion -> Bearer Token -> 替換 Token
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More →

Google Vision API

  • Google Vision API 是什麼?

    Google Cloud’s Vision API offers powerful pre-trained machine learning models through REST and RPC APIs. Assign labels to images and quickly classify them into millions of predefined categories. Detect objects and faces, read printed and handwritten text, and build valuable metadata into your image catalog. Reference

  • Google Vision API 資料協定?

    • Request
      • body
      ​​​​​​​​{ ​​​​​​​​ "requests":[ ​​​​​​​​ { ​​​​​​​​ "image":{ ​​​​​​​​ "content":"/9j/7QBEUGhvdG9zaG9...image contents...fXNWzvDEeYxxxzj/Coa6Bax//Z" ​​​​​​​​ }, ​​​​​​​​ "features":[ ​​​​​​​​ { ​​​​​​​​ "type":"FACE_DETECTION", ​​​​​​​​ "maxResults":10 ​​​​​​​​ } ​​​​​​​​ ] ​​​​​​​​ } ​​​​​​​​ ] ​​​​​​​​}
      • 注意

      content-type 一定要加 charset=UTF-8,否則會噴錯。 e.g. 'content-type': 'application/json; charset=UTF-8'

    • Response Format
      • mid - if present, contains a **machine-generated identifier (MID) corresponding to the entity's Google Knowledge Graph entry. Note that mid values remain unique across different languages, so you can use these values to tie entities together from different languages. To inspect MID values, refer to the Google Knowledge Graph API documentation.
      • description - the label description.
      • score - the confidence score, which ranges from 0 (no confidence) to 1 (very high confidence).
      • topicality - The relevancy of the ICA (Image Content Annotation) label to the image. It measures how important/central a label is to the overall context of a page.
  • Google Vision API Result

    • Input(Convert to Base64):
    • Output
      ​​​​​​​​{ ​​​​​​​​ "returnCode": "200", ​​​​​​​​ "detail": [ ​​​​​​​​ { ​​​​​​​​ "labelAnnotations": [ ​​​​​​​​ { ​​​​​​​​ "mid": "/m/03q69", ​​​​​​​​ "description": "Hair", ​​​​​​​​ "score": 0.9861285, ​​​​​​​​ "topicality": 0.9861285 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0dzct", ​​​​​​​​ "description": "Face", ​​​​​​​​ "score": 0.9857265, ​​​​​​​​ "topicality": 0.9857265 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0k0pj", ​​​​​​​​ "description": "Nose", ​​​​​​​​ "score": 0.98358303, ​​​​​​​​ "topicality": 0.98358303 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/06z04", ​​​​​​​​ "description": "Skin", ​​​​​​​​ "score": 0.9762376, ​​​​​​​​ "topicality": 0.9762376 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/04hgtk", ​​​​​​​​ "description": "Head", ​​​​​​​​ "score": 0.9751926, ​​​​​​​​ "topicality": 0.9751926 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/01dvt1", ​​​​​​​​ "description": "Joint", ​​​​​​​​ "score": 0.9750415, ​​​​​​​​ "topicality": 0.9750415 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/06pj2k", ​​​​​​​​ "description": "Lip", ​​​​​​​​ "score": 0.9707111, ​​​​​​​​ "topicality": 0.9707111 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0f9swq", ​​​​​​​​ "description": "Chin", ​​​​​​​​ "score": 0.96725506, ​​​​​​​​ "topicality": 0.96725506 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0k65p", ​​​​​​​​ "description": "Hand", ​​​​​​​​ "score": 0.9582216, ​​​​​​​​ "topicality": 0.9582216 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/027n3_", ​​​​​​​​ "description": "Eyebrow", ​​​​​​​​ "score": 0.9542992, ​​​​​​​​ "topicality": 0.9542992 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0ds4x", ​​​​​​​​ "description": "Hairstyle", ​​​​​​​​ "score": 0.9509009, ​​​​​​​​ "topicality": 0.9509009 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/01ssh5", ​​​​​​​​ "description": "Shoulder", ​​​​​​​​ "score": 0.9408361, ​​​​​​​​ "topicality": 0.9408361 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/014sv8", ​​​​​​​​ "description": "Eye", ​​​​​​​​ "score": 0.93863827, ​​​​​​​​ "topicality": 0.93863827 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/03f52z", ​​​​​​​​ "description": "Eyelash", ​​​​​​​​ "score": 0.9263171, ​​​​​​​​ "topicality": 0.9263171 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0dzd8", ​​​​​​​​ "description": "Neck", ​​​​​​​​ "score": 0.88831997, ​​​​​​​​ "topicality": 0.88831997 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/02p0tk3", ​​​​​​​​ "description": "Human body", ​​​​​​​​ "score": 0.88534075, ​​​​​​​​ "topicality": 0.88534075 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/032tl", ​​​​​​​​ "description": "Fashion", ​​​​​​​​ "score": 0.88157994, ​​​​​​​​ "topicality": 0.88157994 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/01k9lj", ​​​​​​​​ "description": "Jaw", ​​​​​​​​ "score": 0.88125896, ​​​​​​​​ "topicality": 0.88125896 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/062581", ​​​​​​​​ "description": "Sleeve", ​​​​​​​​ "score": 0.8724503, ​​​​​​​​ "topicality": 0.8724503 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/02qp_b", ​​​​​​​​ "description": "Makeover", ​​​​​​​​ "score": 0.86496717, ​​​​​​​​ "topicality": 0.86496717 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/031974", ​​​​​​​​ "description": "Waist", ​​​​​​​​ "score": 0.8557286, ​​​​​​​​ "topicality": 0.8557286 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0244x1", ​​​​​​​​ "description": "Gesture", ​​​​​​​​ "score": 0.85260487, ​​​​​​​​ "topicality": 0.85260487 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/06c7f7", ​​​​​​​​ "description": "Lipstick", ​​​​​​​​ "score": 0.83878326, ​​​​​​​​ "topicality": 0.83878326 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/02qqd4n", ​​​​​​​​ "description": "Fashion design", ​​​​​​​​ "score": 0.8218539, ​​​​​​​​ "topicality": 0.8218539 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/071j9r", ​​​​​​​​ "description": "Cool", ​​​​​​​​ "score": 0.8132745, ​​​​​​​​ "topicality": 0.8132745 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0fc1fy", ​​​​​​​​ "description": "Black hair", ​​​​​​​​ "score": 0.80930203, ​​​​​​​​ "topicality": 0.80930203 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/09spj9", ​​​​​​​​ "description": "Layered hair", ​​​​​​​​ "score": 0.80235404, ​​​​​​​​ "topicality": 0.80235404 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/02hqr87", ​​​​​​​​ "description": "Fashion model", ​​​​​​​​ "score": 0.8020067, ​​​​​​​​ "topicality": 0.8020067 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/02pd__z", ​​​​​​​​ "description": "Long hair", ​​​​​​​​ "score": 0.7667365, ​​​​​​​​ "topicality": 0.7667365 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/01f43", ​​​​​​​​ "description": "Beauty", ​​​​​​​​ "score": 0.7543108, ​​​​​​​​ "topicality": 0.7543108 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0408t8_", ​​​​​​​​ "description": "Street fashion", ​​​​​​​​ "score": 0.7379927, ​​​​​​​​ "topicality": 0.7379927 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/02ksmb", ​​​​​​​​ "description": "Brown hair", ​​​​​​​​ "score": 0.7225363, ​​​​​​​​ "topicality": 0.7225363 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0294jb", ​​​​​​​​ "description": "Blond", ​​​​​​​​ "score": 0.7196876, ​​​​​​​​ "topicality": 0.7196876 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0404d", ​​​​​​​​ "description": "Jewellery", ​​​​​​​​ "score": 0.7194071, ​​​​​​​​ "topicality": 0.7194071 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/081pkj", ​​​​​​​​ "description": "Event", ​​​​​​​​ "score": 0.70016056, ​​​​​​​​ "topicality": 0.70016056 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/01vm1p", ​​​​​​​​ "description": "Elbow", ​​​​​​​​ "score": 0.6806076, ​​​​​​​​ "topicality": 0.6806076 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0463sg", ​​​​​​​​ "description": "Fashion accessory", ​​​​​​​​ "score": 0.6760009, ​​​​​​​​ "topicality": 0.6760009 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0dzdr", ​​​​​​​​ "description": "Chest", ​​​​​​​​ "score": 0.6736534, ​​​​​​​​ "topicality": 0.6736534 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/03r18y", ​​​​​​​​ "description": "Peach", ​​​​​​​​ "score": 0.6631233, ​​​​​​​​ "topicality": 0.6631233 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0hgs2h_", ​​​​​​​​ "description": "Bridal accessory", ​​​​​​​​ "score": 0.657685, ​​​​​​​​ "topicality": 0.657685 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/028mzr", ​​​​​​​​ "description": "Hair coloring", ​​​​​​​​ "score": 0.6307764, ​​​​​​​​ "topicality": 0.6307764 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0hgsb5g", ​​​​​​​​ "description": "Day dress", ​​​​​​​​ "score": 0.61831653, ​​​​​​​​ "topicality": 0.61831653 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/02w3_2", ​​​​​​​​ "description": "Formal wear", ​​​​​​​​ "score": 0.5906528, ​​​​​​​​ "topicality": 0.5906528 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0cnmr", ​​​​​​​​ "description": "Fur", ​​​​​​​​ "score": 0.5857253, ​​​​​​​​ "topicality": 0.5857253 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/05qdh", ​​​​​​​​ "description": "Painting", ​​​​​​​​ "score": 0.5792883, ​​​​​​​​ "topicality": 0.5792883 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/02qbl1m", ​​​​​​​​ "description": "Photo shoot", ​​​​​​​​ "score": 0.5773519, ​​​​​​​​ "topicality": 0.5773519 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/01dv4h", ​​​​​​​​ "description": "Portrait", ​​​​​​​​ "score": 0.5426634, ​​​​​​​​ "topicality": 0.5426634 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0hwky", ​​​​​​​​ "description": "Pattern", ​​​​​​​​ "score": 0.5369504, ​​​​​​​​ "topicality": 0.5369504 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0d1pc", ​​​​​​​​ "description": "Model", ​​​​​​​​ "score": 0.5320481, ​​​​​​​​ "topicality": 0.5320481 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/0chml9", ​​​​​​​​ "description": "Portrait photography", ​​​​​​​​ "score": 0.50773615, ​​​​​​​​ "topicality": 0.50773615 ​​​​​​​​ } ​​​​​​​​ ], ​​​​​​​​ "localizedObjectAnnotations": [ ​​​​​​​​ { ​​​​​​​​ "mid": "/m/03gx245", ​​​​​​​​ "name": "Top", ​​​​​​​​ "score": 0.77517706, ​​​​​​​​ "boundingPoly": { ​​​​​​​​ "normalizedVertices": [ ​​​​​​​​ { ​​​​​​​​ "x": 0.08164109, ​​​​​​​​ "y": 0.46991932 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.8557673, ​​​​​​​​ "y": 0.46991932 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.8557673, ​​​​​​​​ "y": 0.99705213 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.08164109, ​​​​​​​​ "y": 0.99705213 ​​​​​​​​ } ​​​​​​​​ ] ​​​​​​​​ } ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/01llx7", ​​​​​​​​ "name": "Bracelet", ​​​​​​​​ "score": 0.64256585, ​​​​​​​​ "boundingPoly": { ​​​​​​​​ "normalizedVertices": [ ​​​​​​​​ { ​​​​​​​​ "x": 0.8477685, ​​​​​​​​ "y": 0.33136028 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.94037557, ​​​​​​​​ "y": 0.33136028 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.94037557, ​​​​​​​​ "y": 0.4504279 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.8477685, ​​​​​​​​ "y": 0.4504279 ​​​​​​​​ } ​​​​​​​​ ] ​​​​​​​​ } ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "mid": "/m/01g317", ​​​​​​​​ "name": "Person", ​​​​​​​​ "score": 0.54514444, ​​​​​​​​ "boundingPoly": { ​​​​​​​​ "normalizedVertices": [ ​​​​​​​​ { ​​​​​​​​ "x": 0.0060475226, ​​​​​​​​ "y": 0.018381465 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.9973958, ​​​​​​​​ "y": 0.018381465 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.9973958, ​​​​​​​​ "y": 0.9973958 ​​​​​​​​ }, ​​​​​​​​ { ​​​​​​​​ "x": 0.0060475226, ​​​​​​​​ "y": 0.9973958 ​​​​​​​​ } ​​​​​​​​ ] ​​​​​​​​ } ​​​​​​​​ } ​​​​​​​​ ] ​​​​​​​​ } ​​​​​​​​ ] ​​​​​​​​}

推薦 VSCode 套件 -> Waka Time

  • 協助使用者紀錄寫 Code 的時間

問題討論

  1. JWT 給前端帶?後端帶?
  2. 架構的問題