今天是這週唯一的假日,卻也是個雨天。
兩位快要發霉的工程師提不起勁來寫程式,於是開始分享最近的開發進度。
我首先開口:「昨天試著把首頁 get("/")
移進 authenticate
區塊,發現這樣就是宣告此頁面需要認證,沒登入的話會自動導向登入頁。」
「⋯⋯嗯?這樣做網站的話挺方便的,但是給 App 的 API 不能這樣,應該要回我 HttpStatusCode 401 。」老姐有氣無力的回應。
「當然, API 路徑開頭的不該移進 authenticate
區塊,而是把登入後的資料放在 Session 裡面,藉此來判斷有沒有登入,登入的是哪個使用者。」說到這,我起身拿了零食櫃裡的巧克力豆,倒了一半給老姐後才繼續說:「以 delete API 舉例的話,錯誤會有400 參數格式不對
、401 未認證
、403 使用者沒權限
、404 題目不存在
這幾種。」
install(Sessions) {
cookie<SoupBowlSession>("SESSION")
}
data class SoupBowlSession(val id: String)
delete("/api/topics/{id}") {
val session = call.sessions.get<SoupBowlSession>()
session?.let {
val topicId = try {
UUID.fromString(call.parameters["id"])
} catch (e: Exception) { null }
topicId?.let {
val result = transaction {
Topic.findById(topicId)?.let { it ->
it.takeIf { it.author.toString() == session.id }?.let {
it.delete()
0
} ?: 1
} ?: -1
}
when(result) {
0 -> call.respond(HttpStatusCode.NoContent)
1 -> call.respond(HttpStatusCode.Forbidden)
else -> call.respond(HttpStatusCode.NotFound)
}
} ?: call.respond(HttpStatusCode.BadRequest)
} ?: call.respond(HttpStatusCode.Unauthorized)
}
老姐吃了巧克力豆後恢復了些精神,略微思考後回應:「應該有方法可以整合 session 判斷那邊,否則複製貼上怕漏。」
我點頭附和:「嗯,這邊還在研究,另外, OIDC (OpenID Connect) 那邊從 token 裡拿資料那邊也還在確認,因為不同來源不同屬性命名。」可能一開始先接一兩種就好,先從自己有的帳號開始, Google 、 Facebook 、 Github 。
「我想知道你聊天室最後決定怎麼做?想說先知道的話 Android 這邊能先做準備,等我這邊都弄好了也可以過去幫你。」老姐有點憂心地看著我,因為最近 Ktor 開發比較常碰到問題。
「等弄好 Session 後會嘗試 Ktor 搭配 websocket
協定, Android 那邊應該和串接其他 websocket server 沒什麼差別。」我話剛說完就打了一個哈欠,沒辦法,只好回去補眠了,明天也要提起精神上班呢。
本次鐵人賽的作品在放進更多內容後已經成書,書名是《老姐要用Kotlin寫專案:從 Server 到 Android APP 的開發生存日記》,歡迎購買唷。https://www.tenlong.com.tw/products/9789864348978