Oauth error invalid_request: The redirect_uri is not whitelisted - node.js

I'm trying to develop an app with React and Node based on this documentation:
I followed the tutorial step by step but I'm stuck in testing the app with this URL format:
I replaced the ngrok address and my shopify store but I get the 404 error (This page could not be found.)
I found the same question in this link. So I renamed the .env to process.env but I still have the same problem.
Here is the .env file:
package.json :
server.js :
The error :

I don't think my answer is going to help many , But i am going to put it here anyway. So i had the same issue recently and i tried everything in stack-overflow and shopify community. And finally the problem was i had mistakenly copied my another app's apikey. So even if the apiKey is wrong the error probably you are going to face is the same "The redirect uri is not whitelisted."

Mistake I was doing that I forgot to postpend /auth/callback to Forwarding URL to the Allowed redirection URL(s) section generated by following command:
ngrok http 3000
so redirect url will be like:
https://SOME_STRING.ngrok.io/auth/callback

Yes there is an issue with your callback URL you have to define your app URL and callback URL in your shopify partner account where you create shopify app
Shopify partner account
You have to do as follow
open apps >> yourapp >> app setup >> Insert In URLs(Whitelisted redirection URL(s))
Once you whitelist your URL there then the issue is solve

Your Whitelisted redirection URL must be https

Make sure that App URL and Redirection URL in App Setup is correct
something like -
App URL => https://example.com/
Redirection URL => https://example.com/auth/callback (make sure don't put "/" in the last)
and in your project HOST should be: https://example.com/
this will surely help you!!!

I accidentally used the http address instead of the https one.

I guess that will happen once you restart your ngrok, and your ngrok address url has changed, you have to manually update your new ngrok in the following part:
Your AppUrl and Redirection Url in App setup. (Shopify dashboard)
In your .env file, Where you defined your SHOPIFY_APP_URL. (Code Editor)

I had a '/' at the end of SHOPIFY_APP_URL in the .env file, so the redirect url was wrong with '//auth/callback'

The problem I was facing was that the SHOPIFY_API_KEY and SHOPIFY_API_SECRET in the .env file were in quotes which are the same in your case too. For this quote error also, it was showing the same error. Basically it is the wrong API keys error. Can you try removing quotes and try again?
If that doesn't work, please check you are using HTTPS URL and not HTTP

I stuck in this error for 5-6 hours and it was just because I used ngrok and the https in ngrok is not working very well...
so I upload all of my content to a real server with https subdomain and everything is working fine now

Don't forget to check these for the host variable in your env file:
There should be no trailing / on the URL.
there should be no protocol mentioned for the URL
HOST=abcxyz.com and not HOST:https://abcxyz.com/

[ Solved ] 2022-08-03
I ran into the same error when I was trying to install Shopify App on Shopify Development Store for testing.
Make sure that there are no trailing slashes when copying and pasting the ngrok url in .env file
I was getting this error because I used a trailing slash - https://<Your ngrok url>/
. Using it without trailing slash https://<Your ngrok url> fixed the issue.
Also, make sure that you include the trailing slash in your App Settings in Shopify Admin. Even if you don't include it, Shopify will save it with a trailing slash automatically.
Next, test installing your app. If you see any other error then make sure that you are using proper Shopify API scopes in your .env file.

For me, it was that, in my beginAuth method, I had the whole url as the callback. It just wants the path.
I took it from
let authRoute = await Shopify.Auth.beginAuth(
req,
res,
process.env.SHOPIFY_STORE,
'https://stuff.ngrok.io/auth/shopify/callback',
false
)
to
let authRoute = await Shopify.Auth.beginAuth(
req,
res,
process.env.SHOPIFY_STORE,
'/auth/shopify/callback',
false
)

For me it was because I accidentally commented out the code where I set accessToken and shop

This error occurs when you use HTTP instead of HTTPS in allow redirection links secession in Shopify.

Related

Setting up Swagger Ui in Firebase Functions Server

I've developed an API on Firebase Cloud Functions and I want to include a docs path to it.
I'm using swagger and I could successfully test it locally (localhost:PORT/docs) but when I deploy the function to Firebase it's not working, it redirects me to an authorization page.
I think I figured out why this is:
Let's say the name of my Cloud function is cfunc. Then the base url for it is something like https://region-name-project-name.cloudfunctions.net/cfunc. Based on how I included the swagger documentation:
const swaggerDoc = require('./docs/swagger.config.json')
app.use(
'/docs',
allowCors,
swaggerUi.serve,
swaggerUi.setup(swaggerDoc, {
customCssUrl: '/assets/swagger.css',
customSiteTitle: 'My Function Title',
customfavIcon: '/assets/logo.ico',
swaggerOptions: {
supportedSubmitMethods: [] //to disable the "Try it out" button
}
})
)
the docs should be located at https://region-name-project-name.cloudfunctions.net/cfunc/docs. When I try to access that URL, watching "Network" in my browser DevTools, it attempts a GET at that URL with response 304 and then redirects to https://region-name-project-name.cloudfunctions.net/docs and that's what brings up the Google Authentication page, since there's no Cloud Function named "docs" so Google thinks I'm trying to access something else in Firebase Cloud Functions (the same thing happens if I do something like https://region-name-project-name.cloudfunctions.net/tomato)
But I still don't know how to fix this redirect or why it's happening. I tried adding the Cloud Function URL to the host parameter of the swagger.config.json file, and some modifications to CORS, like allowing more Request Methods, adding json as content type, allowing authentication on headers, but nothing seems to be working.
Hope I was clear enought, if not tell me any other info you need (it's one of my first posts here :B)
Found the SOLUTION
After testing a BUNCH of different things, I found out that the redirection was in fact happening always removing one slice of the path after, for example I changed the docs endpoint to '/something/docs' and when accessing the URL that would be https://region-name-project-name.cloudfunctions.net/cfunc/something/docs it redirected to https://region-name-project-name.cloudfunctions.net/cfunc/docs which did not bring up the Google Authentication thing but now wasn't a valid path for my docs so it returned a 'Cannot GET /cfunc/docs'.
For some reason this redirection DOES NOT happen if you add an extra forward slash ('/') at the end of the documentation URL. So, in the first case, where the endpoint for the documentation is only '/docs', accessing the URL https://region-name-project-name.cloudfunctions.net/cfunc/docs/ does it. I do not know why that is, I'm probably posting an Issue on the swagger repo, but if someone has some extra data on why or how to make it work otherwise it would be awesome to hear.
Hope this helps someone else!
EDIT:
Oh and another thing I forgot, it's apparently better if you setup swagger-ui as if you were using express Router, even if you are not (maybe Firebase loads the Cloud Function with something like a router), so instead of app.use('/docs', swagger-ui.serve, swagger-ui.setup(swagger-file)) do app.use('/docs', swagger-ui.serve) and then app.get('/docs', swagger-ui.setup(swagger-file))

Electron + Vue + msal-nodejs + Azure Ad: redirect URL issue

I'm building a desktop app using Electron and Vue as framework.
I also need to authenticate the user using Azure AD and I'm using msal-node.js as library to do that.
I'm able to authenticate with the server in azure and get the user info, but I cannot figure it out how to set the redirect URL.
First I have to say that the behaviour between dev and prod change drastically and I'm going to explain both scenarios and, in both of them I'm going to use history mode or not
DEV - using createWebHistory
Return Url in Azure and .env file: http://localhost:8080/
This is what I've got from the devTools during the normal navigation (no authenticated)
And this is what I've got after the authentication (the call to the API is successful):
Blank page in the app.
DEV - using createWebHashHistory
Return Url in Azure and .env file: http://localhost:8080/#/
After the authentication (failed):
Blank page in the app.
PROD
In prod I must use createWebHasHistory otherwise I've got blank page from the beginning.
The first problem I've got in production is the url itself.
When I create the window I call the following url:
await win.loadURL('app://./index.html')
In azure I cannot use the same url because it's not a valid url.
If I use just:
await win.loadURL('app://index.html')
I've got blank page
Any idea?
Thank you
The solution I've found it's pretty simple. Probably it's not the most "elegant", but it works, at least for prod. In dev I've still got the same weird problem described above.
Basically I'm starting a node server (localhost:3031 for example), within the app itself, then I'm catching the redirect url with it (localhost:3031/redirect) and serving the internal url from it:
expressApp.get('/redirect', async (req, res) => {
await win.loadURL('app://./index.html#about')
})
As I said, it works and I don't see any security issue with that, but, if you have any other idea or suggestion, please let me know.
Thank you
UPDATE
I've found the issue with Dev as well. In order to authenticate I'm using what Microsoft is suggesting in its documentation.
If you look at the file AuthProvider.js there is this portion of code, at the beginning:
const CUSTOM_FILE_PROTOCOL_NAME = process.env.REDIRECT_URI.split(':')[0];
Down below, in the method "getTokenIteractive" there is this other piece of code that applies the new protocol:
protocol.registerFileProtocol(CUSTOM_FILE_PROTOCOL_NAME, (req, callback) => {
const requestUrl = new URL(req.url)
callback(path.normalize(`${__dirname}/${requestUrl.path}`))
})
In Dev my REDIRECT_URI is "http://localhost:3031/redirect", but the app protocol must be "app" (or whatever you have chosen) in order to work with Vue. So, I've just wrapped this last method in a condition based on the environment and now everything works as expected everywhere.
I hope all this can be useful to someone.
I ran into a similar issue and your solution helped me out, thank you! Can I ask how you handled the logout redirect?
Also have you tried onBeforeRequest to handle the redirects, instead of a node server?
It was used as an example in an auth0 blog: https://auth0.com/blog/securing-electron-applications-with-openid-connect-and-oauth-2/

Always redirect http traffic to https traffic in google app engine nodejs flex environment [duplicate]

I've followed the answer of this: Redirect from http to https in google cloud but it does not seem to be currently accurate any more. The anchor referenced ( https://cloud.google.com/appengine/docs/flexible/nodejs/configuring-your-app-with-app-yaml#security ) seems to have been removed but without a note of a replacement.
For reference, I am serving NodeJS over a Google App (flex) Engine. As per the answer I've got in my app.yaml:
handlers:
- url: /.*
script: IGNORED
secure: always
Since HTTPS is obviously terminated before it hits my Express engine (and redirection on there would be useless); how is it currently correctly implemented?
Potentially helpful, I have an external domain attached via the "Custom domains" tab in the console, and there is indeed a SSL certificate configured (so if a user manually goes to https://.com everything is fine)
The flexible environment does not current support handlers in the app.yaml. If you want https:// redirection, you have a few options:
Use helmet to do to HSTS stuff for you, and implement your own initial redirect.
I wrote a happy little library to always forces SSL on all routes for express yes-https
We are considering auto-redirecting all traffic to SSL by default. Do you think that would be a good thing for your apps?
Pulling Justin's yes-https library, I was able to get this to work:
var app = express();
app.use(function(req, res, next){
if (req.host != 'localhost' && req.get('X-Forwarded-Proto') == 'http') {
res.redirect(`https://${req.host}${req.url}`);
return;
}
app.router(req, res, next);
});
At first I thought I had to do that since I was on an appengine subdomain and couldn't use HSTS. Then I learned HSTS works fine for subdomains. :) Regardless, I thought people might want to see what the magic bit to use was if they didn't want to use yes-https for some reason.
Justin, auto-redirecting all traffic to SSL by default sounds great to me. I just spent hours trying to figure out how to do so before I found this post because I was trying to get my app to get Chrome's add to homescreen install banner as per https://developers.google.com/web/fundamentals/engage-and-retain/app-install-banners/.
GCP This should be as easy to just use the gcloud app cli and configure a header (Strict-Transport-Security) or redirect rule. Perhaps the push is to force us to Firebase Hosting instead which is forcing HTTPS already. For a quick solution for Single Page apps (static content) with React, Angular etc, we can use this JS snippet.
It ignores localhost environments. You can change localhost with a host name that you would like to exclude. It then redirects using https as protocol.
if ( location.host.indexOf("localhost") < 0 && location.protocol.toLowerCase() !== "https:"){
const url= `https://${location.host}`;
location.replace(url);
}

HTTP to HTTPS redirection on App Engine Flexible

I've followed the answer of this: Redirect from http to https in google cloud but it does not seem to be currently accurate any more. The anchor referenced ( https://cloud.google.com/appengine/docs/flexible/nodejs/configuring-your-app-with-app-yaml#security ) seems to have been removed but without a note of a replacement.
For reference, I am serving NodeJS over a Google App (flex) Engine. As per the answer I've got in my app.yaml:
handlers:
- url: /.*
script: IGNORED
secure: always
Since HTTPS is obviously terminated before it hits my Express engine (and redirection on there would be useless); how is it currently correctly implemented?
Potentially helpful, I have an external domain attached via the "Custom domains" tab in the console, and there is indeed a SSL certificate configured (so if a user manually goes to https://.com everything is fine)
The flexible environment does not current support handlers in the app.yaml. If you want https:// redirection, you have a few options:
Use helmet to do to HSTS stuff for you, and implement your own initial redirect.
I wrote a happy little library to always forces SSL on all routes for express yes-https
We are considering auto-redirecting all traffic to SSL by default. Do you think that would be a good thing for your apps?
Pulling Justin's yes-https library, I was able to get this to work:
var app = express();
app.use(function(req, res, next){
if (req.host != 'localhost' && req.get('X-Forwarded-Proto') == 'http') {
res.redirect(`https://${req.host}${req.url}`);
return;
}
app.router(req, res, next);
});
At first I thought I had to do that since I was on an appengine subdomain and couldn't use HSTS. Then I learned HSTS works fine for subdomains. :) Regardless, I thought people might want to see what the magic bit to use was if they didn't want to use yes-https for some reason.
Justin, auto-redirecting all traffic to SSL by default sounds great to me. I just spent hours trying to figure out how to do so before I found this post because I was trying to get my app to get Chrome's add to homescreen install banner as per https://developers.google.com/web/fundamentals/engage-and-retain/app-install-banners/.
GCP This should be as easy to just use the gcloud app cli and configure a header (Strict-Transport-Security) or redirect rule. Perhaps the push is to force us to Firebase Hosting instead which is forcing HTTPS already. For a quick solution for Single Page apps (static content) with React, Angular etc, we can use this JS snippet.
It ignores localhost environments. You can change localhost with a host name that you would like to exclude. It then redirects using https as protocol.
if ( location.host.indexOf("localhost") < 0 && location.protocol.toLowerCase() !== "https:"){
const url= `https://${location.host}`;
location.replace(url);
}

connect-modrewrite to rewrite url

I am running webrtc html on node.js port 8080
I am trying to rewrite the url on node.js
I installed both modules connect-url-rewrite and connect-modrewrite
can you advice me with example and where can add the script on server.js or on html pages itself
Please advice
You don't need both connect-url-rewrite and connect-modrewrite. Pick one of them and go with that.
I'd suggest reading up a little on how Connect middleware works.
Essentially, you create a Connect app, and call use on it, passing in the rewrite function with a set of rules. There's a good example the Github page for connect-modrewrite. I've reposted it here with some simplifications:
var app = connect()
app.use(modRewrite([
'^/test$ /index.html',
'^/test/\\d*$ /index.html [L]',
'^/test/\\d*/\\d*$ /flag.html [L]'
]))
app.use(connect.static(PATH_TO_STATIC_FILES_DIR))
app.listen(3000)
If you don't know what the strings inside of the modRewrite call mean, you'll have to read up a little on rewrite rules. Essentially, the pattern is: <regular expression for url fragment> <target> <optional flags>
Hope that helps!

Resources