什麼是 JWT?
JSON Web Tokens (JWT) 是一種開放式標準 (RFC 7519),用於以 JSON 物件的形式在各方之間安全地傳輸資訊。 JWT 通常用於身份驗證和授權目的。它們由三個部分組成:
- 標頭 HEADER:包含有關令牌的元數據,例如令牌的類型(JWT)和使用的雜湊演算法。
- 有效負載 PAYLOAD:包含聲明,即關於實體(通常是使用者)和附加資料的陳述。
- 簽章:用於驗證令牌的完整性和真實性。
cors 跨來源資源共用
跨來源資源共用(Cross-Origin Resource Sharing (CORS))是一種使用額外 HTTP 標頭令目前瀏覽網站的使用者代理 (en-US)取得存取其他來源(網域)伺服器特定資源權限的機制。當使用者代理請求一個不是目前文件來源——例如來自於不同網域(domain)、通訊協定(protocol)或通訊埠(port)的資源時,會建立一個跨來源 HTTP 請求(cross-origin HTTP request)
安裝cors
1 | npm install cors --save |
啟用所有 CORS 請求
- 載入express
- 載入cors
- use cors
1 | var express = require('express') |
- 載入express
- 載入cors
- 在單一路由加入cors()
1 | var express = require('express') |
Configuring CORS=>配置 CORS
1 | var express = require('express') |
默認配置相當於:
- origin:配置 Access-Control-Allow-Origin CORS 標頭。
- methods:配置 Access-Control-Allow-Methods CORS 標頭。要一個逗號分隔的字符串(例如:'GET,PUT,POST')或一個數組(例如:['GET', 'PUT', 'POST'])。
- allowedHeaders配置 Access-Control-Allow-Headers CORS 標頭。 需要一個逗號分隔的字符串(例如:'Content-Type,Authorization')或一個數組(例如:['Content-Type', 'Authorization'])。 如果未指定,則默認反映請求的 Access-Control-Request-Headers 標頭中指定的標頭。
- exposedHeaders配置 Access-Control-Expose-Headers CORS 標頭。 需要一個逗號分隔的字符串(例如:'Content-Range,X-Content-Range')或一個數組(例如:['Content-Range', 'X-Content-Range'])。 如果未指定,則不會公開任何自定義標頭。
- credentials配置 Access-Control-Allow-Credentials CORS 標頭。 設置為 true 以傳遞標頭,否則將被省略。
- maxAge:配置 Access-Control-Max-Age CORS 標頭。 設置為整數以傳遞標頭,否則將被省略。 preflightContinue:將 CORS 預檢響應傳遞給下一個處理程序。
- preflightContinue:將 CORS 預檢響應傳遞給下一個處理程序。
- optionsSuccessStatus:提供用於成功 OPTIONS 請求的狀態代碼,因為一些舊版瀏覽器(IE11、各種 SmartTV)會在 204 上阻塞。
1 | { |
bcryptjs密碼加密
安裝bcryptjs bcryptjs
密碼加密,此套件的加密是不可逆的,所以沒有辦法從加密後的結果回推原始密碼,相對安全性提高非常多
1 | npm install bcryptjs --save |
異步
1 | const bcrypt = require('bcrypt'); |
技術 1(在單獨的函數呼叫上產生鹽和雜湊值):
bcrypt.hash()
1 | bcrypt.genSalt(saltRounds, function(err, salt) { |
技術 2(自動產生鹽和雜湊值):
bcrypt.hash()
1 | bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) { |
這兩種技術達到相同的最終結果。
要檢查密碼:
1 | // Load hash from your password DB. |
JWT 包含三個重要部分:Header、Payload、Signature。它們一起組合成一個標準結構:header.payload.signature.
客戶端通常在Authorization header 中附加 JWT 和 Bearer 前綴:
1 | Authorization: Bearer [header].[payload].[signature] |
或者僅在x-access-token標頭中:
1 | x-access-token: [header].[payload].[signature] |
Node.js express 和 MongoDB 用戶身份驗證
安裝 jsonwebtoken
1 | npm install jsonwebtoken --save |
產生 JWT
透過模組上的sign()方法可以產生一組 JWT,產生時需要將存放在 Token 當中的資料帶入payload參數中、密鑰帶入secretOrPrivateKey參數中:
1 | jwt.sign(payload, secretOrPrivateKey, [options, callback]) |
options參數非必填,但透過帶入options物件能設定許多選項。例如:
- algorithm:設定產生簽章要使用的雜湊演算法(預設: HS256)
- expiresIn:設定 Token 多久後會過期(自動在 Payload 新增 exp)
- noTimestamp:設定產生 JWD 時不會自動在 Payload 中新增iat時間
callback 參數非必填,但若要以非同步方式產生 JWD,可以提供一個 Callback 函式,Token 將能在 Callback 函式中取得。
1 | // 設定密鑰 |