Node - Oauth2 API [GOT CREATED]

@jwillmer I spend now a lot of time trying to reproduce the issues you are having but I am sadly totally unable to do so. Also with authentication activated (like you have) and executing it in the main process, it always works fine for me.
I can always connect to the service I am testing with (in this case Github) and deleted credentials are always deleted, no matter how often I refresh. Do you have the same issues if you simply start it like described here:

If it does work fine there, what setting you are using does break it? Because if I can not reproduce the bug I sadly do not know how to fix it.

Thanks a lot for your help!

I was able to connect with GitHub. So now I will look into our application. However the delete credentials issue still persists. I let you know if it also happens on a stable image as soon as I have tested it.

1 Like

Great, thanks a lot @jwillmer !

We can’t figure it out. We would need some kind of logging output from N8N to investigate further.

The workflow at the moment is that after a successful login the redirect to N8N times out. We also saw in the logs of our user mgm that N8N wasn’t requesting the Access Token URL.

About your comment:

image

The access token url will be called internally by N8N and not via the user (browser). That means that in our setup the URL needs to have the internal DNS name of the user mgm:

Thanks a lot @jwillmer!

Does the delete issues happen for you on other images?

Ah yes sorry. With “external URL” I did not mean that it has to be really on another server. I meant “external” of n8n. Looks then correct with what you have.

I can however still not understand why it would not work for your internal OAuth2 service. For all the other OAuth2 services we already build integrations for, it works perfectly fine. I saw that your “Authorization URL” uses https. Is it using a valid certificate or is it something self-signed? Because that is the only thing I can come up with right now.

I am using OAuth2 to connect Google Dialogflow API. Most of the things work fine and I can authenticate my client and get the JSON response from Dialogflow as well. However, it seems that the refresh token from the initial response was not saved and it produced the following error when the access token got expired after 3600 seconds.

ERROR: No refresh token

Error: No refresh token
    at ClientOAuth2Token.refresh (/data/node_modules/client-oauth2/src/client-oauth2.js:367:27)
    at /data/packages/core/src/NodeExecuteFunctions.ts:149:34
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at Object.execute (/data/packages/nodes-base/nodes/HttpRequest.node.ts:804:17)
    at /data/packages/core/src/WorkflowExecute.ts:597:26

Here is my HTTP Node’s OAuth settings:

Untitled

Any ideas what could be this problem?

Many thanks!

I can however still not understand why it would not work for your internal OAuth2 service. For all the other OAuth2 services we already build integrations for, it works perfectly fine. I saw that your “Authorization URL” uses https. Is it using a valid certificate or is it something self-signed? Because that is the only thing I can come up with right now.

Do you have an idea how I could debug n8n to monitor the oauth process end find out the issue?

@vanting Sorry to hear that you have problems. Are you using the latest code from Github or the Docker image? Because there should actually always just overwrite the supplied data. So if with the first authentication request the refresh_token gets returned and with the second one not, it should not overwrite it:

Are you sure it got returned? Because the refresh_token does not get returned by default by all services. The most time access_type=offline has to be supplied as query parameter.

@jwillmer the only way to do that is to pull the n8n code locally, add debug messages to the OAuth REST endpoints like this one:


and build it.

1 Like

I am using the docker image n8nio/n8n:0.67.3-oauth-beta. Does it matter?

I did provide the query parameter access_type=offline as you may see it from my screenshot of the OAuth configuration. I tested the whole authentication process with Google’s OAuth Playground and am sure that it will reply with the refresh_token from the first response.

However, I do not know how can I log the response of the HTTP node for debugging. I am very new to n8n. Sorry for my dumb questions.

Ah sorry @vanting did totally overlook that.

In this case the problem could be that you used the same data to authenticate before (could even be a totally different application with different scopes) and for that reason does it not return the refresh_token (as it did the very first time). I just tried to do the same and I had the same problem. You can however force Google to send it every time by adding prompt=consent. Meaning you would have to set:

access_type=offline&prompt=consent

This fix works like a charm! Thanks @jan !

I think I found the issue. Our process breaks on line 1038. I think the reason is that req.originalUrl points to https://usermanagement.central.nightlybuild.dev/... and is not reachable in the docker network. The getToken-function should use the Access Token URL in order to reach the user mgm service.

Sorry do not understand.
If it is not reachable in the Docker network then there is nothing we can do about it. It would then be on you to supply the docker image the needed information.
Apart from that, what the getToken function is doing is default OAuth2 behaviour and works for all services we tested correctly unless I understand something wrong.

This is the problem in my mind:

As long as the communication goes through the browser the domain names can be resolved. But when n8n makes an internal request to user mgm it can’t use the public domain name since both services are running on the same server and don’t have any knowledge about the public domain names. Thats why they need to use the local domain names for the internal communication.

This is why the access token url is different from the authorization url in our configuration:

I believe using the access token url as base url for the getToken-function will solve this issue and does not effect the functionality for other use cases.

Yes, it is would probably solve your problem but it could also break it for everybody else. Also would doing that fix the problem at the wrong location. It would “fix” it somewhere where nothing is wrong. The problem in this case is not that n8n is doing something wrong, the problem is that the docker container is not set up correctly. If we would start doing something like that in the n8n code, it would become very messy and impossible to maintain. So in this case, the simple and correct fix is to do it in docker and tell it how to resolve the domain.

There are multiple ways to do that. By telling docker to use an additional DNS server or by directly telling it where the server with this hostname/domain can be found like in this example:

Hope that helps.

O.K., I will try to add an internal DNS. But I find it strange that I can define the Access Token URL but the implementation ignores the domain and instead uses the one from the request.

Anyway, can I setup a self signed certificate for my user mgm or does n8n need a “valid” certificate to authenticate?

Edit:

I have edit the host file of n8n to make my user mgm reachable. But now I’m getting the following error - I guess n8n does not like my self signed certificate? How can I fix that?

(node:6) UnhandledPromiseRejectionWarning: ConnectionError: Unable to connect to usermanagement.central.nightlybuild.dev:443
at TLSSocket.onError (/data/node_modules/popsicle-transport-http/src/index.ts:706:15)
at Object.onceWrapper (events.js:418:26)
at TLSSocket.emit (events.js:311:20)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21)
(node:6) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:6) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

@jwillmer Sorry, it is possible that I understood you wrong. I am sadly not very experienced in OAuth (and to be honest I really hate it) additionally do I have right now also just very limited time to look into it. So I was mainly following the documentation of the module we are using here:

The AccessToken URL does get used when the OAuth instance does get created. Have no idea how the internals work and how it does get used and where but simply assume it does it correctly.
Because of my lag of OAuth-knowledge do I not want to start to build an own path without knowing exactly what could go wrong or what security and other implications it has. Simply do not want to fix one edge-case to mess something larger up. If I get confirmed that this change is to 100% fine (or I ever find some time to look properly into it myself) I would be totally fine with the change.

Because of the self-signed cert. If that is the problem I think you would have to tell on the OS-Level that the certificate is valid (at least did not see anything on the first sight in the library to do so). Did that once for a docker-registry for which I used one, sadly do not remember right now what I had to do exactly. Anyway think it was quite simply. So I guess if you google it you should find it.

1 Like

Got released with [email protected]

Please keep us informed about issues. Thanks!

4 Likes

Thanks. You are awesome jan the man.