nwunderly / starlette-discord

"Login with Discord" support for Starlette and FastAPI
https://starlette-discord.rtfd.io
MIT License
32 stars 11 forks source link

Send join_guild request with token in header and the access token in the body #24

Closed barealek closed 1 year ago

barealek commented 1 year ago

The current implementation of starlette_discord.DiscordOAuthSession.join_guild - when everything is done "correctly" - results in a 401 error. Discord requires the bot token in the Authorization header and the access token in the body when sending a PUT request to /guilds/{guild_id}/members/{user_id}.

This PR fixes the addressed issue by sending the access token through the request body and token, which is received through the token parameter through the request header.

BeeMoe5 commented 1 year ago

Discord requires the bot token in the Authorization header and the access token in the body when sending a PUT request to /guilds/{guild_id}/members/{user_id}.

In the docs, it says only the access token is required here, so I suspect that we probably are doing something wrong

barealek commented 1 year ago

I also skipped it at first, but it clearly says it in the link you sent. image

I stumbled upon this issue myself, it was the reason i made this PR. I ended up just implementing the request myself using aiohttp, but it would be nice to fix the issue on the package.

barealek commented 1 year ago

Any status?

BeeMoe5 commented 1 year ago

Any status?

after testing your code, both me and nwunder could not get it working. could you share a code example?

barealek commented 1 year ago

I couldn't get your _discord_request method to work, so I just made a httpclient with aiohttp and sent the request.

Here is a working example with my branch:

import uvicorn
from fastapi import FastAPI
from starlette_discord.client import DiscordOAuthClient

CLIENT_ID = "..."
CLIENT_SECRET = "..."
REDIRECT_URI = "http://localhost:456/api/auth/callback"
DISCORD_BOT_TOKEN = "..." # 
SCOPES = ("guilds", "identify", "guilds.join", "email")

app = FastAPI()
client = DiscordOAuthClient(CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, scopes=SCOPES)

@app.get("/login")
async def login_with_discord():
    return client.redirect()

# NOTE: REDIRECT_URI should be this path.
@app.get("/api/auth/callback")
async def callback(code: str):
    user, token = await client.login_return_token(code)
    sess = client.session_from_token(token)
    await sess.join_guild(1135237548206211114, DISCORD_BOT_TOKEN)
    await sess.close()
    return user.json()

uvicorn.run(app, port=456)
barealek commented 1 year ago

Any status on this with the new commits?

nwunderly commented 1 year ago

I'll revisit this on Friday, been busy.

However, when testing I was getting 401 Unauthorized on the request to join the guild despite having all 3 of those scopes and admin permissions on the bot. Does that code work for you?

I'll do some more testing and get it working so I can merge ASAP.

barealek commented 1 year ago

Yes, the code i sent works with my commits

nwunderly commented 1 year ago

Merged, sorry for the delay. Will likely be doing some reworks to this interface in the next few days (I don't love bot token as an arg to join_guild) but figured I'd at least get moving on this. v0.2.2 coming soon.