以前寫了一款簡單的api模糊測試工具,以前系統可使用http Base認證如今改爲session形式並加上了token。html
最簡單的改造方法,是本身先在瀏覽器手動登陸,而後提取出session和token(系統token在整個會話期間可重複使用)填到模糊測試工具中便可。但這種非全自動化的方式不到萬不得已不想用。前端
最直接的方法,最使用requests按登陸流程依次發包登陸便可。但其中的難點是密碼是加密提交的,詢問開發人員說是DES加密;DES加密不難,可是用不一樣的語言編寫的加密算法與別人的結果徹底一致那就比較費工夫。python
最後的方法,那就是使用selenium登陸避開密碼的構造,這種方法的關鍵點在於:selenium是基於圖形界面操做的,沒有直接的辦法能獲取request和response的數據包,在這種狀況下如何獲取session和token。git
本身動web前端的存儲並無很深刻了解,一直想的是如何獲取selenium request和response的數據包從中提取session和token,直到看到這篇文章纔想起前端的變量(尤爲是restful中的全局變量)會放存localStorage和sessionStorage中,從中提取session和token便可。github
下載驅動文件,放到後續python文件同級目錄下或加入到環境變量中便可。其中Chrome驅動要注意Driver版本與瀏覽器版本對應要求。web
Firefox驅動下載地址:https://github.com/mozilla/geckodriver/releases算法
Chrome驅動下載地址:http://chromedriver.chromium.org/downloadschrome
Safari驅動下載地址:https://webkit.org/blog/6900/webdriver-support-in-safari-10/json
Edge驅動下載地址:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/api
pip install selenium
手動登陸系統後,查看存儲情況以下圖所示,sessionid和token分別存儲在sessionStorage的sessionId和token兩個變量中
import json import time from selenium import webdriver from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By class GetSessionAndToken(): def __init__(self): # 啓用無頭模式,可選 browser_options = webdriver.FirefoxOptions() browser_options.add_argument('--headless') browser_options.add_argument('--disable-gpu') self.browser = webdriver.Firefox(firefox_options=browser_options) # self.browser = webdriver.Chrome() # 登陸系統,具體到本身系統時須要自行修改 def login_system(self): # 登陸用戶名密碼,改爲目標系統用戶名密碼 username = "admin" password = "123456" # 登陸頁面url,改爲目標系統登陸頁面 url = "https://10.10.6.93/#login" self.browser.get(url) # 顯性等待,直到用戶名控件加載出來才進行下一步 WebDriverWait(self.browser,20,0.5).until(EC.presence_of_element_located((By.ID,"txtUserName"))) # 填寫用戶名 self.browser.find_element_by_id("txtUserName").send_keys(username) # 填寫密碼 self.browser.find_element_by_id("txtPassword").send_keys(password) # 點擊登陸 self.browser.find_element_by_id("btnLogin").click() # 強制等待5秒,待session和token都成功返回並存到瀏覽器中 # restful隱性等待不太好用?self.browser.implicitly_wait(5) time.sleep(5) # 獲取sessionid def get_sessionid(self): # 是要從localStorage中獲取仍是要從sessionStorage中獲取,具體看目標系統存到哪一個中 # window.sessionStorage和直接寫sessionStorage是等效的 # 必定要使用return,否則獲取到的一直是None # get的Item不必定就叫sessionId,得具體看目標系統把sessionid存到哪一個變量中 sessionid = self.browser.execute_script('return sessionStorage.getItem("sessionId");') # 另外sessionid通常都直接經過返回Set-Cookies頭設置到Cookie中,因此也能夠從Cookie讀取 # 獲取瀏覽器全部Set-Cookie,返回對象是字典列表 # cookies = self.browser.get_cookies() # 獲取單項Cookie,是否是叫sessionId取決於系統存成什麼變量,單項Cookie是字典 # cookie = self.browser.get_cookie("sessionId") # cookie = cookie["value"] # print(f"{cookies}") return sessionid # 獲取token def get_token(self): # 是要從localStorage中獲取仍是要從sessionStorage中獲取,具體看目標系統存到哪一個中 # window.sessionStorage和直接寫sessionStorage是等效的 # 必定要使用return,否則獲取到的一直是None # get的Item不必定就叫token,得具體看目標系統把token存到哪一個變量中 token = self.browser.execute_script('return sessionStorage.getItem("token");') # print(f"{token}") return token def __del__(self): # 退出程序時關閉瀏覽器 self.browser.close() if __name__ == "__main__": obj = GetSessionAndToken() obj.login_system() sessionid = obj.get_sessionid() token = obj.get_token() print(f"sessionid爲: {sessionid}\n" f"token爲: {token}")
參考:
https://pypi.org/project/selenium/
http://www.runoob.com/jsref/prop-win-localstorage.html
https://blog.csdn.net/sinat_34209942/article/details/81235925
https://stackoverflow.com/questions/44102520/python-selenium-local-storage-returns-none