模拟登录的流程
准备工作:
- 尽可能的找开发或者文档了解项目的登录流程。这里一步非常重要能减少很多工作。
这里有几个常见的点,在模拟的时候需要注意:- 请求时需要带上的是“session”还是“token”
- 登录时,token/session 返回的位置是哪里
- 需要重定向登录时,请求需要带上哪些参数
- 如果有多套环境时,不同环境是否有对登录作出限制,例如环境 A 强制校验验证码,环境 B 没有校验
- 确定账号在所在环境能够正常登录
- 了解流程后,最好在浏览器先登录一遍,看看整个流程是否了解。
- 开始写脚本模拟登录
本文章这次记录的是在无文档,通过浏览器查看登录流程,熟悉流程再编写脚本的过程。
通过浏览器查看登录流程
首先先找到登录 rul,然后使用账号密码登录一次,确保网址和账号密码可用。
当登录成功后,可以打开浏览器的控制台查看登录过程中,到底请求了哪些 url(chrome 按 F12,其他浏览器可以邮件鼠标点击“检查”)
这里需要注意两个点:
- 点击 network tab 可以用到请求记录,如果需要重定向,那么点击“all”才可以看到所有请求
- 如果请求速度太慢,还没来得及看请求细节,可以断开网路,或者设置较慢的网路
通过查看请求记录,发现登录需要发起 3 次请求,第一次是登录用户中心获取用户信息,等二次是登录对应项目,第三次是获得项目后台返回的 token
那么我们我们拆开每一次请求来了解其中的过程。
登录用户中心
这一步是登录用户中心,获取帐号的信息。
需要在响应头获取 seesion,和 body 中的用户 ID
直接上代码
def login_user_center(self, username, password, captcha="xxx"):
"""
登陆用户中心获取session和用户id
:param username: 用户名
:param password: 用户密码
:param captcha: 验证码,默认"xxx"
:return: 返回登陆成功的session和用户id
"""
parametrize_data = {
"username": username,
"password": password,
"captcha": captcha
}
# 这里在配置类中获取 login url
url = bc.USERS_CENTER_LOGIN.get("login_url")
# 这里使用requests库发起请求,由于不需要指定header信息,所以没加上
response = requests.post(url=url, data=parametrize_data)
# 获取相应的头
response_headers = response.headers
# 获取响应的body,body转换为json格式
response_json = response.json()
# 使用 logging 库记录响应信息
self.logger.info(
"login_user_center response json:{}, response headers:{}".format(response_json, response_headers))
# 从头信息获取 session 和 id
user_info = []
user_info.append(response_headers.get("Set-Cookie"))
user_info.append(response_json.get("data").get("id"))
self.logger.info("login success, user info:{}".format(user_info))
return user_info
登录项目
公司的项目是这样的架构:
- 有一个统一的用户管理后台,不同项目的用户都在这里管理
- 项目 A,用户登录时需要现在用户中心登录,登录后带上 seesion 和 id 登录项目 A,登录成后返回 token
- 项目 B,用户登录时需要现在用户中心登录,登录后带上 seesion 和 id 登录项目 B,登录成后返回 token
需要注意的是登录项目时,请求的是用户中心专用的重定向接口,接口带上需要登录的项目 url,登录成功后会返回获取 token url
直接上代码
def login_project_A(self, user_info):
"""
登陆项目A后台获取 token
:param user_info: 登陆用户中心返回的session和id
:return: 返回token
"""
# 通过配置类获取项目A某个页面的url,拼接成重定向url
parametrize_data = {
"redirect_url": "{}/v1/ucenter/callback?audience=tyre_admin&callback="
"{}}/dist/dashboard".format(self.env.get("project_A_host"), self.env.get("project_A_host"))}
# header 带上 session
headers = {
"Cookie": user_info[0]
}
# 这里通过用户中心专用的重定向接口发起请求,需要注意的是cookies重的token一定是str,不能是int
response = requests.get(url=bc.USERS_CENTER_LOGIN.get("token_url"), params=parametrize_data, headers=headers,
cookies={"token": str(user_info[1])})
self.logger.info("response data:{}".format(response.text))
# 响应的body内容是一个html代码,这里直接通过正则表达式匹配,也可以通过bs4的BeautifulSoup去匹配
# 从响应中使用正则表达式匹配token url
token_url = re.findall(r"= '(.+)';", response.text)[0]
self.logger.info("token_url:{}".format(token_url))
return token_url
获取项目的 token
上一步成功登录后,返回的 html 带有获取 token 的 url,最后一步就是通过 url 发起请求。请求后会再次重定向,重定向后的 url 带有 token,通过正则表达式获取后就可以正常测试了。
# 使用token url 发起请求获取token
def get_token(self, token_url):
token_response = requests.get(url=token_url)
# 从响应中获得重定向的url,然后截取url中的token
callback_token_url = token_response.url
#匹配 token
token = re.findall(r"toekn=(.*)", callback_token_url)
return token
总结
到这里,登录就算完成了,后续每个请求都带上 token 就可以正常请求了。
当时我直接使用浏览器抓请求熟悉登录流程,过程真是曲折。如果可以的话,还是直接问问开发或者看文档会比较省时省力!
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于