使用字符串格式在请求 header 中发送的 JSON 负载中隐藏用户名和密码

Use string formatting to hide username and password in JSON payload sent in request header

我有一个函数,其参数带有用户名和密码。我想使用 f 字符串或任何类型的字符串格式,这样我就不必在代码中硬编码用户名和密码,而是替换传递给函数的那些参数,因为它违反了安全要求。

有效载荷必须采用如下所示的格式,除非有另一种可能在 JSON 中发送有效载荷。因为我猜这需要通过 JSON 发送。如果我尝试删除反斜杠,它会出现缩进错误。

我如何利用字符串格式来隐藏用户名和密码,以便我可以在运行时提供这些信息。

import requests
import sys, pprint, json
from getpass import getpass
from multiprocessing import Pool
import yaml
from functools import partial

http_header = {}
url_dict = {}

def getCookie(username, password, ip_addr):

    url = "https://"+ip_addr+"/api/aaaLogin.json"

    # payload = " {\r\n\"aaaUser\":"\
    #           " {\r\n\"attributes\":"\
    #           " {\r\n\"name\": \"admin\",\r\n" \
    #           "  \"pwd\":\"Admin_1234!\"\r\n" \
    #           " }\r\n " \
    #           " }\r\n }\r\n"

    payload = {
        # 'aaaUser':'',
        # 'attributes':'',
        'name': username,
        'pwd': password,
    }
    json_payload = json.dumps(payload)

    headers = {
        'Content-Type': "application/json",
        'Cache-Control': "no-cache",
    }

    try:

        req = requests.request("POST", url=url, data=json_payload, headers=headers, verify=False)
    except:
        print('Failed to obtain auth cookie: %s' % (e))
        sys.exit(1)
    else:
        cookie=req.headers['Set-Cookie']
        # print(cookie)
        return cookie

def genericGetRequest(ip_addr, cookie, apiurl, verb):
    url = 'https://'+ip_addr+apiurl
    http_header["Cookie"]=cookie
    http_header["Host"]=ip_addr
    try:
        req = requests.request(verb, url=url, headers=http_header, verify=False)
    except:
        print("There is a problem with the {} request!".format(verb))
    else:
        return(req)

def getResults(username, password, ip):
    cookie=getCookie(username, password, ip)
    if cookie:
        print("User is logged in. Auth-cookie is  %s\n" % cookie)
        vlan_list = []
        trunk_vlans_dict = {}
        for i in range(1, 49):
            apiurl = f"/api/mo/sys/intf/phys-[eth1/{i}]/.json"
            generic = genericGetRequest(ip, cookie, apiurl, 'GET')
            generic = generic.json()
            imdata = generic['imdata']
            vlan = imdata[0]['l1PhysIf']['attributes']
            trunk_vlans_dict[f"eth1/{i}"] = vlan['trunkVlans']
        vlan_list.append(trunk_vlans_dict)
        print(vlan_list)

if __name__ == '__main__':
    username = input("Enter username: ")
    print("Enter password")
    password = getpass()


    if password:
        deviceListFile = 'nexus_list.yaml'
        with open(deviceListFile) as f:
            deviceList = yaml.load(f)

        num_threads = 5
        print("Retreiving Configuration: ")
        pool = Pool(num_threads)
        partial_getResults = partial(getResults, username, password)
        pool.map(partial_getResults, deviceList)
        pool.close()
        pool.join()
    else:
        print("Passwords do not match. Exiting...")

使用 json 转储后,我收到另一个错误,如下所示。顺便说一句,为了清楚起见,我已经发布了整个代码。

ssh://vrxxx@werssefsf:22/sdfsdfsdfsdf/Python_Dev/Test1/pyVENV/bin/python -u /NetworkAutomation/Python_Dev/Test1/nxos_test5.py
Enter username: admin
admin
Enter password
Password: Admin_1234!

/NetworkAutomation/Python_Dev/Test1/nxos_test5.py:82: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
  deviceList = yaml.load(f)
Retreiving Configuration: 
/NetworkAutomation/Python_Dev/Test1/pyVENV/lib/python3.7/site-packages/urllib3/connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)
multiprocessing.pool.RemoteTraceback: 
"""
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/multiprocessing/pool.py", line 121, in worker
    result = (True, func(*args, **kwds))
  File "/usr/local/lib/python3.7/multiprocessing/pool.py", line 44, in mapstar
    return list(map(*args))
  File "/NetworkAutomation/Python_Dev/Test1/nxos_test5.py", line 58, in getResults
    cookie=getCookie(username, password, ip)
  File "/NetworkAutomation/Python_Dev/Test1/nxos_test5.py", line 42, in getCookie
    cookie=req.headers['Set-Cookie']
  File "/NetworkAutomation/Python_Dev/Test1/pyVENV/lib/python3.7/site-packages/requests/structures.py", line 52, in __getitem__
    return self._store[key.lower()][1]
KeyError: 'set-cookie'
"""

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/NetworkAutomation/Python_Dev/Test1/nxos_test5.py", line 88, in <module>
    pool.map(partial_getResults, deviceList)
  File "/usr/local/lib/python3.7/multiprocessing/pool.py", line 268, in map
    return self._map_async(func, iterable, mapstar, chunksize).get()
  File "/usr/local/lib/python3.7/multiprocessing/pool.py", line 657, in get
    raise self._value
KeyError: 'set-cookie'

Process finished with exit code 1

没有最简单的例子很难回答你的问题。也不清楚 aaaUser、属性和 ip_addr 的用途,但我认为这就是您要实现的目标:

    import json
    
    def getCookie(username, password, ip_addr):
        payload = {
            'name': username,
            'pwd': password
        }
        return json.dumps(payload)
    
    print(getCookie(username='admin', password='Admin_1234', ip_addr="127.0.0.0"))
    # {"name": "admin", "pwd": "Admin_1234"}

不太可能需要所有新行和字符串格式,您只需通过 json 转储方法传递 Python 字典。

谢谢强尼。你的建议奏效了。我只需要使用嵌套字典格式的 aaaUser 和属性,如下所示。

payload = {
    'aaaUser': {
    'attributes': {
    'name': username,
    'pwd': password,
}}}
json_payload = json.dumps(payload)