forked from Maojuan-lang/SenKongDao
-
Notifications
You must be signed in to change notification settings - Fork 0
/
headersGenerator.py
89 lines (80 loc) · 3.12 KB
/
headersGenerator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import hashlib
import hmac
import json
import time
from urllib import parse
import requests
import constants
# headers参数解密来源于Gitee作者xxyz30
# 原仓库地址:https://gitee.com/FancyCabbage/skyland-auto-sign
# 常量引入
cred_code_url = constants.cred_code_url
grant_code_url = constants.grant_code_url
app_version = constants.app_version
app_code = constants.app_code
header_login = {
'User-Agent': 'Skland/'+app_version+' (com.hypergryph.skland; build:100001014; Android 31; ) Okhttp/4.11.0',
'Accept-Encoding': 'gzip',
'Connection': 'close'
}
header_for_sign = {
'platform': '1',
'timestamp': '',
'dId': '',
'vName': app_version
}
def get_grant_code(token):
response = requests.post(grant_code_url, json={
'appCode': app_code,
'token': token,
'type': 0
}, headers=header_login)
resp = response.json()
if response.status_code != 200:
raise Exception(f'获得认证代码失败:{resp}')
if resp.get('status') != 0:
raise Exception(f'获得认证代码失败:{resp["msg"]}')
return resp['data']['code']
def get_cred_by_token(token):
grant_code = get_grant_code(token)
return get_cred(grant_code)
def get_cred(grant):
resp = requests.post(cred_code_url, json={
'code': grant,
'kind': 1
}, headers=header_login).json()
if resp['code'] != 0:
raise Exception(f'获得cred失败:{resp["message"]}')
return resp['data']
def get_sign_header(url: str, method, body, old_header,sign_token):
h = json.loads(json.dumps(old_header))
p = parse.urlparse(url)
if method.lower() == 'get':
h['sign'], header_ca = generate_signature(sign_token, p.path, p.query)
else:
h['sign'], header_ca = generate_signature(sign_token, p.path, json.dumps(body))
for i in header_ca:
h[i] = header_ca[i]
return h
def generate_signature(token: str, path, body_or_query):
"""
获得签名头
接口地址+方法为Get请求?用query否则用body+时间戳+ 请求头的四个重要参数(dId,platform,timestamp,vName).toJSON()
将此字符串做HMAC加密,算法为SHA-256,密钥token为请求cred接口会返回的一个token值
再将加密后的字符串做MD5即得到sign
:param token: 拿cred时候的token
:param path: 请求路径(不包括网址)
:param body_or_query: 如果是GET,则是它的query。POST则为它的body
:return: 计算完毕的sign
"""
# 总是说请勿修改设备时间,怕不是yj你的服务器有问题吧,所以这里特地-2
t = str(int(time.time()) - 2)
token = token.encode('utf-8')
header_ca = json.loads(json.dumps(header_for_sign))
header_ca['timestamp'] = t
header_ca_str = json.dumps(header_ca, separators=(',', ':'))
s = path + body_or_query + t + header_ca_str
hex_s = hmac.new(token, s.encode('utf-8'), hashlib.sha256).hexdigest()
md5 = hashlib.md5(hex_s.encode('utf-8')).hexdigest().encode('utf-8').decode('utf-8')
print(f'算出签名: {md5}')
return md5, header_ca