如何将我的路由包装在身份验证指令中,然后为我的路由提供自定义类的可见性以供访问

Bla*_*man 6 authentication akka-http

我的 API 客户端将在标头或查询字符串中传递会话令牌,如下所示:

Http Header with key/value like MyApp-Token abc123
Url:
  https://api.example.com/v1/board?authToken=abc123

 val secureRoutes =
        authenticateToken() { authenticatedContext =>
           path("board") {
             get {
               complete(s"board#index route ${authenticatedContext.user.username}")
             }
           }
       }
Run Code Online (Sandbox Code Playgroud)

是否有一个内置指令可以为我执行此操作,或者我是否必须以某种方式创建自己的自定义指令,该指令将首先查看 HTTP 标头,如果不存在,则查看是否有查询字符串值钥匙authToken

如果我必须创建自定义指令,我可以遵循或学习哪些示例?

我知道我可以使用内置指令获取 HTTP 标头:

          headerValueByName("x-authToken") { authToken =>
            get {
              complete(s"board#index route 2.1 $authToken")
            }
          }
Run Code Online (Sandbox Code Playgroud)

还有一个从查询字符串中获取值的指令:

  parameter("authToken") { authToken => 

  ...
  }
Run Code Online (Sandbox Code Playgroud)

我如何将它们结合起来,然后在内部我想要进行数据库调用,然后我不想返回,而是authToken想返回一个自定义案例类,该类将包含我刚刚从数据库加载的数据,例如:

case class AuthenticatedContext(authToken: String, user: User, ...)
Run Code Online (Sandbox Code Playgroud)

Sha*_*tri 1

我们始终可以构造自定义指令或组合指令,如下所示:

case class AuthenticatedContext(authToken: String)

  def validateTokenAndGetAuthContext(token: String): Future[AuthenticatedContext] = {
    Future.successful(AuthenticatedContext(token))
  }

  val authToken: Directive1[AuthenticatedContext] = optionalHeaderValueByName("authToken").flatMap {
    case Some(token) =>
      onComplete(validateTokenAndGetAuthContext(token)).flatMap {
        case Failure(_) => reject(AuthorizationFailedRejection)
        case Success(value) => provide(value)
      }
    case None =>
      parameter("authToken".optional).flatMap {
        case Some(token) =>
          onComplete(validateTokenAndGetAuthContext(token)).flatMap {
            case Failure(_) => reject(AuthorizationFailedRejection)
            case Success(value) => provide(value)
          }
        case None => reject(AuthorizationFailedRejection)
      }
  }
Run Code Online (Sandbox Code Playgroud)

它是使用 HeaderDirectives、ParameterDirectives 和 FuturesDirectives 构建的。