ChatWork does not give me access token

19 Views Asked by At

I am trying to make a small app to send messages to the ChatWork app. I manage to get the code from the authorization when I sign in, but when I try to use this code to generate the token, I am getting 401. So, really do not know what I am doing wrong. I appreciate your help. This is the code:

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)

This is the documentation: http://download.chatwork.com/ChatWork_API_Documentation.pdf

The type of client has to be set up as confidential, otherwise you won't get client_secret.

1

There are 1 best solutions below

0
Luis Alejandro Vargas Ramos On BEST ANSWER

I solved the issue. First, setting up the account as public, then change the response without encoding (The documentation was a bit misleading here). This is the full code working:

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)
    ```