76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
import requests
|
|
import time
|
|
|
|
# 1. 定义应用凭据
|
|
client_id = 'XXXXXXXXXXXXXX' # 替换为你的应用 ID
|
|
scope = 'offline_access user.read mail.read' # 确保权限范围正确
|
|
|
|
# 2. 获取设备代码
|
|
device_url = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode'
|
|
device_response = requests.post(device_url, data={
|
|
'client_id': client_id,
|
|
'scope': scope
|
|
})
|
|
|
|
# 检查请求是否成功
|
|
if device_response.status_code != 200:
|
|
print(f"Failed to get device code. Status code: {device_response.status_code}")
|
|
print(f"Error response: {device_response.text}")
|
|
exit()
|
|
|
|
# 解析设备代码响应
|
|
device_data = device_response.json()
|
|
print("Device data:", device_data)
|
|
|
|
# 确保 device_code 存在
|
|
if 'device_code' not in device_data:
|
|
print("Error: 'device_code' not found in device data")
|
|
exit()
|
|
|
|
device_code = device_data['device_code']
|
|
user_code = device_data['user_code']
|
|
verification_url = device_data['verification_uri']
|
|
interval = device_data.get('interval', 5) # 默认间隔时间 5 秒
|
|
|
|
print(f"Please navigate to {verification_url} and enter the code: {user_code}")
|
|
|
|
# 3. 等待用户完成身份验证
|
|
timeout = time.time() + 900 # 15 分钟超时
|
|
authorized = False
|
|
|
|
while time.time() < timeout:
|
|
time.sleep(interval)
|
|
|
|
token_url = 'https://login.microsoftonline.com/consumers/oauth2/v2.0/token'
|
|
token_response = requests.post(token_url, data={
|
|
'client_id': client_id,
|
|
'device_code': device_code,
|
|
'grant_type': 'urn:ietf:params:oauth:grant-type:device_code'
|
|
})
|
|
|
|
if token_response.status_code == 200:
|
|
authorized = True
|
|
break
|
|
elif token_response.status_code == 400:
|
|
error = token_response.json().get('error')
|
|
if error != 'authorization_pending':
|
|
print(f"An error occurred: {error}")
|
|
print(f"Error response: {token_response.json()}")
|
|
break
|
|
|
|
if not authorized:
|
|
print("Authorization timed out.")
|
|
else:
|
|
# 4. 获取访问令牌
|
|
token_data = token_response.json()
|
|
access_token = token_data['access_token']
|
|
refresh_token = token_data['refresh_token']
|
|
print("Access token acquired successfully!")
|
|
|
|
# 5. 使用访问令牌调用受保护的资源
|
|
user_info_url = 'https://graph.microsoft.com/v1.0/me'
|
|
headers = {
|
|
'Authorization': f'Bearer {access_token}'
|
|
}
|
|
user_info_response = requests.get(user_info_url, headers=headers)
|
|
print("User information:", user_info_response.json()) |