0

这是一些有效的 bash 代码:

COOKIE_FILE=cookies.txt
DOMAIN="http://localhost:9000"

function login {
  URL_LOGIN="$DOMAIN/asfd/asdf"

  rm -f "$COOKIE_FILE"
  curl -s \
    -H "Content-type: application/x-www-form-urlencoded" \
    -c "$COOKIE_FILE" \
    -d "username=asdf" \
    -d "password=asdf" \
    -L "$URL_LOGIN" > /dev/null
  if [ -f "$COOKIE_FILE" ]; then
    GREP="grep -P"
    if [ $OSTYPE == *darwin* ]; then GREP=grep; fi
    COOKIE=`$GREP "\tid\t" "$COOKIE_FILE"`
    if [ -z "$COOKIE" ]; then
      echo "Login failed; check your userid and password"
      exit -2
    else
      echo "Cookie is: $COOKIE"
    fi
  else
    echo "Problem: $COOKIE_FILE does not exist"
    exit -3
  fi
}

这是我对在 JVM 11 上运行的 Scala 2.13 的类似代码的尝试(非 Scala 程序员应该通过稍微眯眼就能轻松阅读此代码)。

trait HTTPLike {
  def ofFormData(data: immutable.Map[String, String]): HttpRequest.BodyPublisher = {
    val builder = new StringBuilder
    data.foreach { entry =>
      if (builder.nonEmpty) builder.append("&")
      builder.append(URLEncoder.encode(entry._1.toString, StandardCharsets.UTF_8))
      builder.append("=")
      builder.append(URLEncoder.encode(entry._2.toString, StandardCharsets.UTF_8))
    }
    BodyPublishers.ofString(builder.toString)
  }
}

trait HTTPLike extends HTTPLike {
  import java.net.http.HttpClient.Redirect
  import java.net.http.HttpResponse.BodyHandlers
  import java.net.http.{HttpClient, HttpRequest, HttpResponse}
  import java.net.{CookieHandler, URI}
  import scala.collection.immutable
  import scala.jdk.OptionConverters._

  private val domainStr = "http://localhost:9000"

  private val uriLogin: URI = URI.create(s"$domainStr/asdf/asdf")

  CookieHandler.setDefault(new CookieManager)
  CookieHandler.getDefault.asInstanceOf[CookieManager]
    .setCookiePolicy(CookiePolicy.ACCEPT_ALL)

  private val client: HttpClient = HttpClient.newBuilder
    .cookieHandler(CookieHandler.getDefault)
    .followRedirects(Redirect.NORMAL)
    .build

  private val loginData: Map[String, String] = immutable.Map("username" -> "asdf", "password" -> "asdf")

  private val requestLogin: HttpRequest = HttpRequest.newBuilder
    .uri(uriLogin)
    .header("Content-Type", "application/x-www-form-urlencoded")
    .POST(ofFormData(loginData))
    .build

  def maybeLoginCookie: Option[String] = {
    val loginResponse: HttpResponse[String] = client.send(requestLogin, BodyHandlers.ofString)
    val idCookie: Option[String] = loginResponse.headers.firstValue("id").toScala
    idCookie
  }
}

maybeLoginCookie从其他地方调用。

即使我看到身份验证有效,我也没有得到 cookie。问题可能与我如何初始化 HTTP 客户端的 cookie 处理有关吗?

4

0 回答 0