在AdonisJs設計中,原本只有Cntroller Method可以取得context(簡寫ctx),但在某些特殊情境下需要取得ctx,且無法透過controller傳遞參數怎麼辦呢?
小編在官網上尋找答案只找到可以使用以下方法,但在實際運行卻什麼也取不到,程式碼如下:
import HttpContext from '@ioc:Adonis/Core/HttpContext'
class SomeService {
public async someOperation() {
const ctx = HttpContext.get()
}
}
應該是缺少一點東西,小編把get改成getOrFail,讓他把錯誤印出來,錯誤訊息顯示
E_INVALID_ALS_ACCESS: HTTP context is not available. Set "useAsyncLocalStorage" to true inside "config/app.ts" file
所以應該是少了設定,只是這設定要加在哪裡,官方文件上只有文字描述要加設定,卻沒有告訴你怎麼做,加在哪。好在config/app.ts裡面設定也不多,一個一個嘗試後是加在
export const http: ServerConfig = {
...... // 中間忽略
useAsyncLocalStorage: true,
}
以下看個使用情境
import { BaseModel, column, beforeSave } from "@ioc:Adonis/Lucid/Orm"
import Hash from "@ioc:Adonis/Core/Hash"
import HttpContext from "@ioc:Adonis/Core/HttpContext"
export default class User extends BaseModel {
@column({ serializeAs: null })
public password: string
@beforeSave()
public static async beforeSave(user: User) {
// 當路由名稱為approve時,實際命名方法如下
// Route.post('xxx', 'XxxController.method').as('approve')
if (HttpContext.get()?.route?.name == "approve") {
return
}
if (user.$dirty.password) {
user.password = await Hash.make(user.password)
}
}
}
基本上在user password改變的前提下都需要經過加密,但就是有某些特殊場景不用,但又懶得把邏輯拆出來到service見一次做一次,只好用這個訪法去完成。
另外還有一個解法,是當判斷
user.password.startsWith("$argon2")
但這有一些問題,例如加密的方法如果改用不是argon lib加密,開頭就會變,或是他就是需要加密在加密。這些往往會變成bug,不過也是要看需求拉。以上就是這次簡短分享,也算做個筆記。
沒有留言:
張貼留言