ChatWork未提供访问令牌

0 投票
1 回答
17 浏览
提问于 2025-04-12 18:25

我正在尝试制作一个小应用程序,用来给ChatWork应用发送消息。我在登录时成功获取了授权代码,但当我用这个代码生成令牌时,却出现了401错误。所以,我真的不知道自己哪里出错了。感谢你的帮助。以下是我的代码:

import requests
from urllib.parse import urlencode, urlparse, parse_qs
import hashlib
import base64
import secrets

# Your ChatWork OAuth 2.0 client ID and redirect URI
client_id = "my_client_ID"
client_secret = "my_client_secret"
redirect_uri = "https://example.com/"
state = "343ab3341331218786ef" # This is for CSRF staff

# URL for the OAuth 2.0 authorization and token endpoints
auth_endpoint = "https://www.chatwork.com/packages/oauth2/login.php"
token_endpoint = "https://oauth.chatwork.com/token"

# Generate a code verifier
code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b'=').decode('utf-8')

# Calculate the code challenge
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).decode('utf-8').replace('=', '')

# Parameters for the authorization request
params = {
    "response_type": "code",
    "client_id": client_id,
    "redirect_uri": redirect_uri,
    "scope": "rooms.all:read_write",
    "state": state,  
    "code_challenge": code_challenge,
    "code_challenge_method": "S256"
}

# Construct the authorization URL
auth_url = auth_endpoint + "?" + urlencode(params)

# Print the authorization URL
print("Open this URL in your browser and authorize the application:")
print(auth_url)

# After the user authorizes the application, they will be redirected to your redirect URI
# Parse the authorization code from the redirect URI
authorization_code = input("Enter the authorization code from the redirect URI (or leave empty if denied): ")
parsed_url = urlparse(authorization_code)
query_params = parse_qs(parsed_url.query)
code = query_params["code"][0]
print(code)

if not code:
    print("Authorization denied by user.")
    # Handle the denial, such as displaying a message to the user or redirecting them to a different page
else:
    # Parameters for the token request
    token_params = {
        "grant_type": "authorization_code",
        "code": code,
        "client_id": client_id,
        "redirect_uri": redirect_uri,
        "code_verifier": code_verifier
    }

    # Make a POST request to the token endpoint to exchange the authorization code for an access token
    response = requests.post(token_endpoint, data=token_params, headers={"Authorization": "Basic " + base64.b64encode(f"{client_id}:{client_secret}".encode('utf-8')).decode('utf-8')})
    print(response)

    # Parse the access token from the response
    access_token = response.json().get('access_token')
    print(access_token)

这是相关的文档: http://download.chatwork.com/ChatWork_API_Documentation.pdf

客户端类型必须设置为保密模式,否则你将无法获得client_secret

1 个回答

0

我解决了这个问题。首先,把账户设置为公开,然后在不进行编码的情况下更改响应(文档在这里有点误导)。这是完整的可运行代码:

import requests
from urllib.parse import urlencode, urlparse, parse_qs
import hashlib
import base64
import secrets

# Your ChatWork OAuth 2.0 client ID and redirect URI
client_id = "your_client_id"
redirect_uri = "https://example.com/"
state = "343ab3341331218786ef"

# URL for the OAuth 2.0 authorization and token endpoints
auth_endpoint = "https://www.chatwork.com/packages/oauth2/login.php"
token_endpoint = "https://oauth.chatwork.com/token"

# Generate a code verifier
code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b'=').decode('utf-8')

# Calculate the code challenge
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).decode('utf-8').replace('=', '')

# Parameters for the authorization request
params = {
    "response_type": "code",
    "client_id": client_id,
    "redirect_uri": redirect_uri,
    "scope": "rooms.all:read_write",
    "state": state,  # Generate a random string for CSRF protection
    "code_challenge": code_challenge,
    "code_challenge_method": "S256"
}

# Construct the authorization URL
auth_url = auth_endpoint + "?" + urlencode(params)

# Print the authorization URL
print("Open this URL in your browser and authorize the application:")
print(auth_url)

# After the user authorizes the application, they will be redirected to your redirect URI
# Parse the authorization code from the redirect URI
authorization_code = input("Enter the authorization code from the redirect URI (or leave empty if denied): ")
parsed_url = urlparse(authorization_code)
query_params = parse_qs(parsed_url.query)
code = query_params["code"][0]
print(code)

if not code:
    print("Authorization denied by user.")
    # Handle the denial, such as displaying a message to the user or redirecting them to a different page
else:
    # Parameters for the token request
    token_params = {
        "grant_type": "authorization_code",
        "client_id": client_id,
        "code": code,
        "redirect_uri": redirect_uri,
        "code_verifier": code_verifier
    }

    response = requests.post(token_endpoint, data=token_params)
    print(response.json())

    # Parse the access token from the response
    access_token = response.json().get('access_token')
    print(access_token)
    ```

撰写回答