Redirect uri
-
Hello,
I would like to integrate fusion auth along with a web application of mine, in which I need the users to log in using fusion auth.
If I understand correctly, my web application must communicate with the fusion auth instance via a middleware, in this case I used the fusionauthclient. I have my web application in dev mode (port 3001) and the fusionauth-example-node (port 3000) running in the same machine, while my fusion auth instance running on a different remote machine.
Before the integration with my application, I am trying to make the fusion-auth-example-node work using the fusion auth instance from the other machine which has a different IP address. While I have changed the redirect parameters in the routes/index.js file and the fusionauthURL as well, the redirect_uri parameter is sticked to "localhost", once the login button is pressed, causing a fusion auth redirect uri error.
Please keep in mind that the IP addresses and the clientId and clientSecret are not real values in this post.
The error which occurs is this:
{
"error" : "invalid_request",
"error_description" : "Invalid redirect uri http://localhost:3000/oauth-redirect",
"error_reason" : "invalid_redirect_uri"
}At this point I noticed that the complete uri has this form:
http://92.123.98.201:9011/oauth2/authorize?client_id=98909b30-hrg1-4141-93fb-387b9846bb94&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Foauth-redirect&scope=offline_access&state=8h7qqzysl3pglw1wlapm8s5guxu8l7saotgxfw2sadyo3kczm4nt7hu0wpudwhnnf3a&code_challenge=A7UFTcMEPUoRn0VXlixkqbHv61EPeN502sx0YgwiMjs&code_challenge_method=S256I think I am missing something regarding maybe the FusionAuthClient settings? If I replace the word localhost with the IP address of the machine which hosts the fusion-auth-example everything works great.
Can you help please?
Thank you in advance!This is my routed/index.js
const express = require('express'); const router = express.Router(); const {FusionAuthClient} = require('@fusionauth/typescript-client'); // tag::clientIdSecret[] const clientId = '98909b30-hrg1-4141-93fb-387b9846bb94'; const clientSecret = '30MVe3dfW-BToE4Oxxr0QnuIAr7odj_ahCDtCT6Qpd0'; // end::clientIdSecret[] const fusionAuthURL = 'http://92.123.98.201:9011'; const client = new FusionAuthClient('noapikeyneeded', fusionAuthURL); const pkceChallenge = require('pkce-challenge'); /* logout home page. */ router.get('/logout', function (req, res, next) { req.session.destroy(); res.redirect(302, 'http://92.123.98.202:3000/'); }); /* GET home page. */ router.get('/', function (req, res, next) { const stateValue = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); req.session.stateValue = stateValue; console.log("home page: " + req.session.stateValue); //generate the pkce challenge/verifier dict const pkce_pair = pkceChallenge(); // Store the PKCE verifier in session req.session.verifier = pkce_pair['code_verifier']; const challenge = pkce_pair['code_challenge']; res.render('index', {user: req.session.user, title: 'FusionAuth Example', clientId: clientId, challenge: challenge, stateValue: stateValue, fusionAuthURL: fusionAuthURL}); }); // tag::fullOAuthCodeExchange[] /* OAuth return from FusionAuth */ router.get('/oauth-redirect', function (req, res, next) { const stateFromServer = req.query.state; if (stateFromServer !== req.session.stateValue) { console.log("State doesn't match. uh-oh."); console.log("Saw: " + stateFromServer + ", but expected: " + req.session.stateValue); res.redirect(302, 'http://92.123.98.202:3000/'); return; } // tag::exchangeOAuthCode[] // This code stores the user in a server-side session client.exchangeOAuthCodeForAccessTokenUsingPKCE(req.query.code, clientId, clientSecret, "http://92.123.98.202/oauth-redirect", req.session.verifier) // end::exchangeOAuthCode[] .then((response) => { console.log(response.response.access_token); return client.retrieveUserUsingJWT(response.response.access_token); }) .then((response) => { if (!response.response.user.registrations || response.response.user.registrations.length == 0 || (response.response.user.registrations.filter(reg => reg.applicationId === clientId)).length == 0) { console.log("User not registered, not authorized."); res.redirect(302, 'http://92.123.98.202:3000/'); return; } // tag::setUserInSession[] req.session.user = response.response.user; }) // end::setUserInSession[] .then((response) => { res.redirect(302, 'http://92.123.98.202:3000/'); }).catch((err) => {console.log("in error"); console.error(JSON.stringify(err));}); // This code pushes the access and refresh tokens back to the browser as secure, HTTP-only cookies // .then((response) => { // res.cookie('access_token', response.response.access_token, {httpOnly: true}); // res.cookie('refresh_token', response.response.refresh_token, {httpOnly: true}); // res.redirect(302, '/'); // }).catch((err) => {console.log("in error"); console.error(JSON.stringify(err));}); }); // end::fullOAuthCodeExchange[] module.exports = router;
-
Can you confirm where/how you are building this link?
If you are using something like our five minute guide, this link is built in the pug template in the views. You may have to make adjustments there.
https://github.com/FusionAuth/fusionauth-example-node
Thanks,
Josh