-
-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discord auth invalid state #218
Comments
If you didn't touch anything and now it doesn't work anymore it might be a Discord issue? Let us know if you find any clue on why that cookie is not transmitted any longer. |
this is where it breaks down since the state is stored in a cookie |
I dont know man... You pass request to generateStateFunction? |
my code is at the top of the conversation my problem is with the way the state is stored now, on my side the cookie is not set so the state is invalid. |
Given that you have not touched anything, how did stop working? Did anything else change? |
just this package version |
This essentially contradicts your original post. You actually changed something. It's hard to help if the repoorts are not clear. What version were you using before? |
as there was ^ in front of the package version, well that's where it took the version above and that's why npm i had to update it |
hi @mcollina, reading the whole thread as third party, as I have problems with fastify-oauth2 as well. You write that his post contradicts with his original post which is not correct. I think there is something not working correctly since 7.2. As far as I can see is that "invalid state" occurs when "getAccessTokenFromAuthorizationCodeFlow" is called.
Maybe the state does need to come from the cookie aswell know? It would be great if someone with a deeper knowledge of this project and code could have a deeper look. Your help is really appreciate. |
thank you for understanding what i said. and glad to hear i'm not the only one. |
where google sets it in his cookies is unimportant. When you get a redirect to your callback site, the code has to be in the query. Thats why it takes it from the request.query.code. Also If you can create me a repository,which i can clone and test, and provide me a link where it shows how to get the creds for discord, I could debug it. |
Just to to recap what the bug report is. Your Discord integration used to work as expected in v7.1.1. Then you updated to v7.2.0 and it stopped working. Can you include some code that shows how you are integrating this library? The way the bug report was originally written seemed that Discord changed their APIs somehow and the integration stopped working. Please read carefully this article from StackOverflow: https://stackoverflow.com/help/minimal-reproducible-example. |
i didn't update it's npm that did it because the version in my package was ^7.1.1 but as there was ^ npm took the liberty of installing 7.2.0 when using npm i Code where I configure how to use the fastify-oauth2 package const discordConfig = oauthPlugin.DISCORD_CONFIGURATION;
fastify.register(oauthPlugin, {
name: "Discord",
credentials: {
client: {
id: config.auth.discord.id,
secret: config.auth.discord.secret,
},
auth: discordConfig,
},
startRedirectPath: "/discord/login",
callbackUri: `${config.api.baseUrl}/v1/auth/callback/discord`,
scope: config.auth.discord.scopes, // guilds identify
prompt: config.auth.discord.prompt, // consent
}); |
Your code seems correct. I will add the "bug" label to this issue. Anytime you create a mvce and provide a link for setting it up, you can ping me up and I will look into it. |
There is no temporary solution for this, because nobody is willing to provide a mvce (repository to clone) with information how to set up an discord oauth login. If people report screenshots and code snippets, than I wont sit at my PC and type it from the image, nor will I puzzle with the code snippet till I get a reproducable example. I am very well aware of oauth2 and openid protocol, and I am developing myself an openid provider. But I dont use this plugin. So dont expect anything, from my side. |
I'm confident in the current implementation, so I would need some help from you to have an easy-to-reproduce way for this (including the client side code). Given the CSRF issue and this bug, I guess your implementation was relying on the fact that |
Although I'm not the thread creator, since I've noticed similar issues with Google, I could build a simple example with login page and matching route and make it available at glitch.com for remixing or upload the repository here. Just let me know if this is suitable and if so, which variant is preferred. |
I just need something to debug easily. So repo here would be nice. |
So I have set up a simple repo on github now: Its a one pager with a google login button. I also set up a .env file. Maybe you need to change urls in src/pages/index.hbs and server.js. But I am not sure if this works, because the project url and callback uri are also set in the google developer console itself. For completeness here is the original on glitch: Please let me know in case of problems or if you need anything further. |
@marco-ippolito PTAL |
from what I can see from your snippet:
the request at |
hi @marco-ippolito, thanks for your feedback! I reworked my code and did the following:
Now that I am able to see the state in But to be honest, reading the project readme, examples and additional how-to resources on the web for this project, I thought it would be easier. Perhaps the documentation just needs to be expanded and made a bit more precise. .register(oauthPlugin, {
name: "googleOAuth2",
scope: ["profile", "email"],
credentials: {
client: {
id: process.env.GOOGLE_OAUTH_CLIENT_ID,
secret: process.env.GOOGLE_OAUTH_CLIENT_SECRET,
},
auth: oauthPlugin.GOOGLE_CONFIGURATION, // plugin-provided configurations for Google OAuth
},
// startRedirectPath: "/login/google", // This is automatically registered as a GET route in your app
callbackUri:
`https://${process.env.PROJECT_DOMAIN}.glitch.me` +
"/login/google/callback", // relative path that serves HTML or an absolute URL
callbackUriParams: {
// custom query param that will be passed to callbackUri
access_type: "offline", // will tell Google to send a refreshToken too
},
})
.after(() => {
/*
Standard Site
*/
fastify.route({
method: ["GET", "HEAD"],
url: "/",
logLevel: "warn",
handler: async (request, reply) => {
let params; // gets passed to template
return reply.
view("/src/pages/index.hbs", params);
},
});
/*
Google OAuth2 Callback
*/
fastify.route({
method: ["POST"],
url: "/login/google/callback",
logLevel: "warn",
handler: async (request, reply) => {
let paramsGoogle = {result: null,}; // gets passed to template
let url = require('url');
try {
const authorizationEndpoint = await fastify.googleOAuth2.generateAuthorizationUri(request, reply);
let state = url.parse(authorizationEndpoint, true);
paramsGoogle.result = state.query.state; // gets printed on front page
return reply
.status(200)
.view("/src/pages/index.hbs", paramsGoogle);
} catch (error) {
paramsGoogle.result = error; // gets printed on front page
return reply
.status(500)
.view("/src/pages/index.hbs", paramsGoogle);
}
},
});
}); |
@LiezarZ I don't have the "state" problem anymore, don't know why, it just work. When I don't know why, I usually say that it's the cache 😅 |
@LiezarZ I'm not sure that's the right approach.
|
Thanks @marco-ippolito but I unfortunately does not understand that. |
@LiezarZ For info, here how I implemented my auth flow in import { FastifyInstance } from "fastify";
import fastifyOauth2 from "@fastify/oauth2";
import { IdTokenClaims } from "../../types";
import { ShinzoError } from "../helpers";
export default async (fastify: FastifyInstance) => {
const container = fastify.container;
fastify.register(fastifyOauth2, {
name: "google",
credentials: {
auth: fastifyOauth2.GOOGLE_CONFIGURATION,
client: {
id: process.env.GOOGLE_CLIENT_ID,
secret: process.env.GOOGLE_CLIENT_SECRET,
},
},
scope: ["profile", "email"],
startRedirectPath: "/google",
callbackUri: `${process.env.BASE_URL}/auth/google/callback`,
});
fastify.route({
method: "GET",
url: "/google/callback",
handler: async (req, res) => {
const { token } = await fastify.google.getAccessTokenFromAuthorizationCodeFlow(req);
const claims = container.tokenService.decode<IdTokenClaims>(token.id_token as string);
if (claims.isError()) throw new ShinzoError(claims.value);
if (!claims.value.email) throw new ShinzoError({ kind: "Unauthorized", message: "Forbidden" });
const user = await container.userRepository.save({
email: claims.value.email,
avatar: claims.value.picture,
firstName: claims.value.given_name,
lastName: claims.value.family_name,
});
if (user.isError()) throw new ShinzoError(user.value);
const jwt = await container.tokenService.sign({ id: user.value });
if (jwt.isError()) throw new ShinzoError(jwt.value);
return res.redirect(`${process.env.WEB_URL}?token=${jwt.value}`);
},
});
}; I'm using the |
@carere many thanks for posting your code and your help! But unfortunately I still cant get it to work. :( @marco-ippolito I also tried your hint and using Out of curiosity I set up another test project this evening and used fastify-passport for google oauth. There my setup works. I get an filled requested with cookies, user data etc. and I would assume that Many thanks again for all your help and have a great evening! |
Looks like the request.cookies['oauth2-redirect-state'] isnt getting populated by Google when it hits the callback. Just ran into this issue. I am only getting a POC together so dont have much time to debug further but I just overwrote the default checkState and generateState to get around it for the time being.
|
Google is not the one responsible for the I was also scratching my head as to why this cookie wasn't set, even though it was present in the request headers when visiting the Let me explain. By default, when you don't set a path when registering a cookie, as per RFC6265, the user agent will use the "directory" of the request-uri's path component as the default value. This essentially means that if your You have 2 options:
|
Prerequisites
Issue
hello !
As of today, my login system with discord no longer works, I don't think I've touched anything.
on my calback url
the cookie doesnt exist :/
The text was updated successfully, but these errors were encountered: