前言
在 AWS 的 API gateway 上就有一個項目(Authorizer
)是支援 Cognito 以及客制認證的方法,好處就是在進我們寫的 API 之前有個可以做身份確認的 Lambda Function 幫我們好前處理,而本篇則會介紹如何在 Serverless framework 上設定 API gateway 的 Authorizer 以及成功讓 API 回應,串接 Cognito 做使用部分就留給之後吧!
👉 本篇的範例全都在 GitHub
API Gateway - Authorizer
擁有 Authorizer 的一個 Serverless 服務會長這樣:
User Request - [Authorizer] - API - Response user
好處除了前言所提到的前處理外,還有如果設定是 Edge
模式 (不是透過 region
從網路層傳) 的話其實在認證完後傳到 API 時速度是很快的。
以下就開始好好的介紹它 😆
實際的位置
如果在這邊設定覺得不知道在哪邊的話可以參考 - 純手動用法官方教學
中文的話左邊名為授權方
,英文則是Authorizer
Serverless 實作
Yaml settings
原始如果串接 python WSGI 的話設定檔應該會長得如下:
1 | functions: |
設定 Authorizer Lambda function,先在跟 api
同層加上 Authorizer
Lambda,指定 handler 為 handler 資料夾
下的 authorizer.py
的 auth_handler
function,並且設定 cors
為 true,避免呼叫 api 時被 AWS 擋下來無法使用。
接著在把 events
裡的兩個事件加上 authorizer
的 Function,名為 ResourceAuthorizer
,改編過後入下:
1 | functions: |
- 這部分參考來自 Serverless docs
只要透過簡單的設定 function 就可以互相溝通是不是很像 docker compose 呀 😏
處理 Lambda function handler
參考並複製官方的範例程式會看到我的開頭要從 event
取得 token:
1 | event_token = event.get('authorizationToken') |
🐛🐛 這裡雖然是取
authorizationToken
,不過呼叫 api 時 header 是要帶Authorization
,如此一來 Api gateway 才會收到對的值,這邊是需要注意 AWS 比較不一樣的地方!
參考支援在這啦 QQ
取得 token 後一般就會做身份驗證的部分,以我的例子來說我就是解 JWT 下來做驗證,這邊為了 Demo 就先不處理它。
產生 Auth Policy
官方提供的範例版本是 Node.js[參考資料],但畢竟我們是用 python 看著 javascript 我怎麼用啊!!
因此查了一番找到了範例: aws-apigateway-lambda-authorizer-blueprints,只是說沒有任何文件使用起來只能靠本能了 😭,這邊他很佛心的提供 dotnet
、golang
、python
、java
、node.js
以及 rust
的範例,基本上常在 Serverless 上跑的語言都有了,就只好放過它一馬了 😇
基本上從官方的範例終止需要改寫成像我專案這樣只要注意 auth_handler
裡面的內容需要填什麼即可。
其他需要注意的就如第 25 行的 policy以及 28 行的 build policy所產出的東西需要確認清楚才行:
1 | policy.allowAllMethods() |
而下面的 class code 就可以先忽略不管,因為那些官方是為了產生出 Authorizer 回應狀態 pattern 所使用的 code,即便我們去改也出不了什麼作用:
1 | class HttpVerb: |
Lambda 回應狀態
Authorizer 認證成功之後 Lambda 會回傳給 API Gateway 的 pattern:
1 | { |
認證失敗回傳的樣子:
1 | { |
這些都會是透過 AuthPolicy 來產生的,直接對 Function return value 是部會作用的。
使用心得 (踩坑)
- Header 收的名稱是
Authorization
,但程式是收authorizationToken
,參考。 - 只能 raise Exception(‘Unauthorized’),多一字少一字都不行,真的很奇怪,參考。
- 好不容易找到的範例預設是會先
deny
掉使用者,但這在測行為會很困擾,官方範例 code。
結論
以往都要使用框架(Flask, Django…)裡提供的功能實作 middleware 來做處理,但若使用像 AWS、Google、Azure 他們 Serverless 服務的話不妨使用 Authorizer 來做驗證,除了認證使用者以外還可以藉由這些 Function Service 來降低 API 的負載,讓它們可以更專心地處理後端邏輯的問題。
如果真的很想知道 Authorizer 的行為機制的話可以看看這篇官方文件 - 使用 postman 去測試 authorizer