Skip to content

Latest commit

 

History

History
107 lines (80 loc) · 2.93 KB

middleware.md

File metadata and controls

107 lines (80 loc) · 2.93 KB

ミドルウェア

戻る

目次

API

proc middleware*(
  self:var Routes,
  path:Regex,
  action:proc(r:Request, p:Params):Future[Response]
) =

proc middleware*(
  self:var Routes,
  httpMethods:seq[HttpMethod],
  path:Regex,
  action:proc(r:Request, p:Params):Future[Response]
) =

proc next*(status:HttpCode=HttpCode(200), body="", headers:Headers=newHeaders()):Response =

サンプル

ミドルウェアはコントローラーが呼ばれる前に実行されます。
下のサンプルソースでは、app/middleware/auth_middlware.nimに定義されているcheckCsrfTokenMiddleware()checkSessionIdMiddleware()が動きます。

main.nim

import basolato
import app/middlewares/auth_middleware


let ROUTES = @[
  Route.get("/", welcome_rontroller.index)
    .middleware(auth_middleware.checkLoginIdMiddleware)
]

serve(routes)

app/middleware/auth_middlware.nim

import asyncdispatch
import basolato/middleware


proc checkLoginId*(r:Request, p:Params):Future[Response] {.async.} =
  if not r.headers.hasKey("X-login-id"):
    return render(Http403, "リクエストヘッダーにX-login-idがありません")

  if not r.headers.hasKey("X-login-token"):
    return render(Http403, "リクエストヘッダーにX-login-tokenがありません")

  return next()

もしリクエストヘッダーにX-login-id or X-login-tokenのどちらかがなければ、403を返し、そうでなければ200を返します。


ログインチェックが失敗した時にログインページにリダイレクトさせたい時は、errorRedirect関数を使うことができます。これは HTTP 303を返します。

app/middleware/auth_middlware.nim

import basolato/middleware

proc checkLoginId*(r:Request, p:Params):Future[Response] {.async.} =
  if not r.headers.hasKey("X-login-id"):
    return errorRedirect("/login")

  if not r.headers.hasKey("X-login-token"):
    return errorRedirect("/login")

  return next()

CORSのように、コントローラーではなくミドルウェアで作られたレスポンスをクライアントに返したい時は、next関数の引数に設定することができます。 以下の例では、setCorsMiddlewareOPTIONSメソッドでのリクエストの時のみ動きます。

main.nim

let ROUTES = @[
  Route.put("/api/user/{id:int}", user_controller.update)
    .middleware(cors_middleware.setCorsMiddleware),
]

app/middleware/cors_middlware.nim

proc setCorsMiddleware*(r:Request, p:Params):Future[Response] {.async.} =
  if r.httpMethod == HttpOption:
    let headers = corsHeader() & secureHeader()
    return next(status=Http204, headers=headers)