21

PowerShell 技巧 - Invoke-WebRequest 存取具 Session 狀態網頁

 3 years ago
source link: https://blog.darkthread.net/blog/invoke-webrequest-w-session/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
Invoke-WebRequest 存取具 Session 狀態網頁-黑暗執行緒

在 PowerShell 要爬網站或存取網頁,Invoke-WebRequest 是不二選擇。有時我們會存取具有 Session 狀態的網頁,例如:要先登入後才能存取某些功能、或在 A 網頁儲存設定後到 B 網頁看結果。實務上 Session 概念多半依賴 Cookie 實現 (相關原理可參考 再探 ASP.NET 大排長龍問題的實驗觀察,ASP.NET 用到 Session 物件時寫入 ASP.NET_Session_Id),換言之,只要在送出 HTTP Request 正確附加 Cookie,就可存取該 Session 的狀態。除了 Session 之外,登入身分也幾乎都是靠 Cookie 實現,透過編碼或加密過的識別字串,供伺服器端檢核及識別登入者。

HttpWebRequest 有個 CookieContainer 屬性做為儲存 Cookie 的容器,從頭到尾使用同一個 CookieContainer 存取不同網頁,CookieContainer 便會保留各網站寫入的 Cookie,後續存取時附上,實現像瀏覽器能記住登入身分或 Session 的效果。PowerShell Invoke-WebRequest 底層是用 HttpWebRequest 實做,自然也支援此一功能。

設計以下實驗驗證。寫一個超簡單的 ASP.NET 網頁存入 Session 變數並導向另一個顯示 Session 變數內容的頁面:(SaveSession.aspx)

<%@Page Language="C#"%>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
	if (string.IsNullOrEmpty(Request["s"])) 
		Response.Write("Invalid Request");
	else 
	{
		Session["State"] = Request["s"];
		Response.Redirect("ShowSession.aspx");
	}
}
</script>

顯示 Session 變數的程式如下:(ShowSession.aspx)

<%@Page Language="C#"%>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
	Response.Write("Session=" + (Session["State"] ?? "NA"));
}
</script>

一般 Invoke-WebRequest 是不會記憶 Cookie 的,因此,呼叫 SaveSession.aspx 直接被導向 ShowSession.aspx 因為 Cookie 剛寫入有帶入,能正確顯示 Session 變數內容。但再次呼叫 ShowSession.aspx 時,並未附上剛才寫入的 Cookie,看不到剛才的 Session 變數。

# Invoke-WebRequest 預設不會記憶 Cookie / Session
(Invoke-WebRequest -Uri http://localhost/aspnet/sessiondemo/savesession.aspx?s=Jeffrey).Content
(Invoke-WebRequest -Uri http://localhost/aspnet/sessiondemo/showsession.aspx).Content

Invoke-WebRequest 有個 -SessionVariable 及 -WebSession 參數,第一次使用時寫 -SessionVariable 變數名稱(注意,不用加 $ 符號),之後 Invoke-WebRequest 時加上 -WebSession $變數名稱 (注意:要加 $),就可以沿用 Cookie 了。「$變數名稱」會是一個 WebRequestSession 物件,其中的 Cookie 屬性就是 Sysetm.Net.CookieContainer:

# 使用 -SessionVariable 建立 WebRequestSession 物件,注意變數名稱前方不用加 $
(Invoke-WebRequest -Uri http://localhost/aspnet/sessiondemo/savesession.aspx?s=Jeffrey -SessionVariable Sess).Content
# 後續使用 -WebSession 帶入 WebRequestSession 物件,可保存 Cookie 狀態,對映 ASP.NET Session
(Invoke-WebRequest -Uri http://localhost/aspnet/sessiondemo/showsession.aspx -WebSession $Sess).Content
# 不帶入 -WebSession 則無法取得 ASP.NET Session 資料
(Invoke-WebRequest -Uri http://localhost/aspnet/sessiondemo/showsession.aspx).Content

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK