这是一些有效的 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 处理有关吗?