Odd problem with Bearer Authentication

I have a problem that I can't figure out and hope someone here can shed some light on.

In my flows I use an http request node to login to a service which returns a (very long) bearer token called idToken.

I then pass that to a function node which sets the headers like:

var idToken = msg.payload.idToken
msg = {}
msg.payload = {}
msg.headers = {};
msg.headers['Authorization'] = "Bearer " + idToken;

I then pass this to a get request in a new http request node (which has Use authentication unchecked).

This does not work (returning 401 unauthorized) But... If I copy the idToken from debug output, check the Use authentication tickbox, select Bearer and paste in the token manually the request works fine.

This is not a solution since the token times out after around twenty minutes.

The question is what could the built in bearer authentication be doing that my 'headers' are not, and/or is it possible to pass the token using mustache format or similar rather than in the headers.

For what it is worth this is a (now timed out) bearer token interesting for being long if nothing else:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Im5pcGVnZWdpQHJvdW5kYnJpdGFpbiIsIm5hbWUiOiJOaXBlZ2lnaSBSb3VuZCBCcml0YWluIiwicm9sZSI6InVzZXIiLCJzY29wZXMiOltdLCJpc3MiOiJodHRwczovL2FwaS5pcmlzLmxyLm9yZyIsInN1YiI6Im5pcGVnZWdpQHJvdW5kYnJpdGFpbiIsImlhdCI6MTU2MTAxNjcxOCwiZXhwIjoxNTYxMDIwMzE4fQ.tbNFf5I_C4-xSePEL_EDDfmJ0br1z0NplwBtnDwIScxGWUYYY0-qSN2VUvyKXzIAGSmVkroix6KTMIMa8mToclteR6dKq8PkEvBorXAkDq84dL2peUhHUilVNY3Sc-bH3Er59OGdW7R_dbwzYSzryJShCP0mMVWhB3Y7NccWVJGZ7LAL4pY50uTDBm8LU-CrRLfoAmkumtGqdwQrc0bBkYEHrMdjVjNlRjzazRlzT0KWlafgWFJ71n8ZY-18wI4cJeGnv9flfuBfL_KfTPWU5cYe_zqCKtTodTJWfdFOLmx1QM6tpqksxEGucfUvUIzkMFhym1MGqIloL8ejb1cu7TBaInMZgVJFcl6gSxu2Z6MJaoo4zgoAN3QhwztxjOOATL5LnOo9htfCOvymEBdNW9lAizjmregnXpjIm6CsrmhS7IUH3FEwSQMdBaZB0_H3NfwBfOMedRDWsoSyDu7YlOqf86dUOVGOe7XABGX3HZpDYnwfsWaSbImPsdLshoKsWyydYiMXcpSx2SW_22YmyzqkM_5afaD-g-ey0fkGF4cFDc_QB47I2I3XXtmggz3JCldDWV5b5nyjucMcPLSTGpfufFpVHi8r_WHpyPoBT4l0znNvq_5zZb3J5nCz73j7fG9Y1tB1bgQuTkLkZpiiSYrQbfrrXbz1ajga_kjWJJ0

Thanks

It is a very long token since it is a Json Web Token (JWT).

You seem to be using it correctly. I don´t know why the authorization is failing.

This is the second reporting I see about the token working in the http request node but not working when configured in a msg.header. The other case is reported in Stack Overflow.

Thanks for looking, yes, it's very puzzling. I wonder if it could be related to timing at the server end, that the token is not valid until the TCP connection is closed on the first request. Something along those lines. I tried putting a delay node in of up to 4 seconds but this did not improve things. Sadly I've got no access to the server logs or support to see what's going on there.

The report on stack overflow suggests that only the word 'Bearer' appeared and not the actual token. Is there something in the handling of the headers that does not expect spaces in the header values (which is quite uncommon)?

Where do I find the source code for the http request node to have a look around?

Perhaps you could try the tool recommended in SO to capture the outgoing request and see if the token is being added or not.

This is the link to the http request node.

Yes, just tried it and can confirm that HTTP Toolkit (which is a pretty neat tool I didn't know existed) does show the header as authorization: Bearer with the token missing in the failing case when the header is provided in the message.

1 Like

For reference, here is a decent description of the authorisation header and why "bearer" is needed.

1 Like

I just installed the intercept tool and got a different result. The token is being added to the request.

Testng flow:

[{"id":"3e5d52e0.12c83e","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"97f4ea7c.6d1af8","type":"http request","z":"3e5d52e0.12c83e","name":"","method":"GET","ret":"txt","paytoqs":false,"url":"https://api.iris.lr.org","tls":"","proxy":"","authType":"basic","x":550,"y":140,"wires":[["54b9bd3c.a946e4"]]},{"id":"f3e9b0b4.8cd01","type":"function","z":"3e5d52e0.12c83e","name":"","func":"var idToken = msg.payload.idToken;\nmsg = {};\nmsg.payload = {};\nmsg.headers = {};\nmsg.headers['Authorization'] = \"Bearer \" + idToken;\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":140,"wires":[["97f4ea7c.6d1af8","14491e14.1d0f92"]]},{"id":"c0de7b49.c548e8","type":"inject","z":"3e5d52e0.12c83e","name":"","topic":"","payload":"{\"idToken\":\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Im5pcGVnZWdpQHJvdW5kYnJpdGFpbiIsIm5hbWUiOiJOaXBlZ2lnaSBSb3VuZCBCcml0YWluIiwicm9sZSI6InVzZXIiLCJzY29wZXMiOltdLCJpc3MiOiJodHRwczovL2FwaS5pcmlzLmxyLm9yZyIsInN1YiI6Im5pcGVnZWdpQHJvdW5kYnJpdGFpbiIsImlhdCI6MTU2MTAxNjcxOCwiZXhwIjoxNTYxMDIwMzE4fQ.tbNFf5I_C4-xSePEL_EDDfmJ0br1z0NplwBtnDwIScxGWUYYY0-qSN2VUvyKXzIAGSmVkroix6KTMIMa8mToclteR6dKq8PkEvBorXAkDq84dL2peUhHUilVNY3Sc-bH3Er59OGdW7R_dbwzYSzryJShCP0mMVWhB3Y7NccWVJGZ7LAL4pY50uTDBm8LU-CrRLfoAmkumtGqdwQrc0bBkYEHrMdjVjNlRjzazRlzT0KWlafgWFJ71n8ZY-18wI4cJeGnv9flfuBfL_KfTPWU5cYe_zqCKtTodTJWfdFOLmx1QM6tpqksxEGucfUvUIzkMFhym1MGqIloL8ejb1cu7TBaInMZgVJFcl6gSxu2Z6MJaoo4zgoAN3QhwztxjOOATL5LnOo9htfCOvymEBdNW9lAizjmregnXpjIm6CsrmhS7IUH3FEwSQMdBaZB0_H3NfwBfOMedRDWsoSyDu7YlOqf86dUOVGOe7XABGX3HZpDYnwfsWaSbImPsdLshoKsWyydYiMXcpSx2SW_22YmyzqkM_5afaD-g-ey0fkGF4cFDc_QB47I2I3XXtmggz3JCldDWV5b5nyjucMcPLSTGpfufFpVHi8r_WHpyPoBT4l0znNvq_5zZb3J5nCz73j7fG9Y1tB1bgQuTkLkZpiiSYrQbfrrXbz1ajga_kjWJJ0\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":140,"wires":[["f3e9b0b4.8cd01","dd0fc7dc.931b48"]]},{"id":"dd0fc7dc.931b48","type":"debug","z":"3e5d52e0.12c83e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":320,"y":240,"wires":[]},{"id":"14491e14.1d0f92","type":"debug","z":"3e5d52e0.12c83e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":510,"y":240,"wires":[]},{"id":"54b9bd3c.a946e4","type":"debug","z":"3e5d52e0.12c83e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":730,"y":140,"wires":[]}]

That's funny. I've just tested it without setting the header in the function node at all and I still see the empty header: Authorization: Bearer with no token. It is as if the checkbox is not switching off the injection of that header.

I think I'm getting somewhere. If I set the 'use authentication' and select 'basic' without giving a password or user, then save the node the whole thing starts to work. I.e. I get the correct header and a 200 response (sending the token in the header).

What seems to be happening is that selecting 'bearer' authentication in the node is not properly disabled by unchecking the box, and just continues to overwrite the header with the now empty token that it has.

1 Like

Good catch.

Depending on what version of Node-RED you are using - if it isn't the latest, you'll need to try that. Then you might wish to raise an issue.

1 Like

Thanks.

Yes, it's a fresh install.

Workaround: Go to the http request node, select Use authentication, select basic authentication, leave username and password blank, select Done to save. On returning the 'use authentication' will be deselected. Authorization header should now be passed correctly when set in the incoming message.

I'll raise it as an issue.

2 Likes

I think I am seeing something similar - and I tired the workaround to no avail.

When I try to use bearer in my http req node, I paste in the token, then I hit done. I come back and the node has bearer selected but there are two text boxes now: username and password. If I pick basic or unselect authentication it does the same thing.

I am using 20.7 on a rasp pi and I can tell it isn't working-meaning this isn't just some ui quirk - because I get back an unauthorized from my endpoint.

Any thoughts on what I can look for or try out?

I have the same problem. Have tried the "basic authentication" work around but to no avail.
I am on Raspberry Pi with the latest Node-Red, 20.8.
Are there any other solutions to this? My application requires a new bearer token every 60 minutes :frowning:

You could try updating to the latest version of Node-RED which is currently v1.0.2

But please read the blog posts about the changes first

Morning @ukmoose,
Unfortunately it seems that this problem is also on recent versions (e.g. 1.0.1):

bearer_auth

Depending on the authentication type, some fields need to become visible and others invisible. This is arranged in the 'change' event handler of the dropdown:

            $("#node-input-authType-select").on("change", function() {
                var val = $(this).val();
                $("#node-input-authType").val(val);
                if (val === "basic" || val === "digest") {
                    $(".node-input-basic-row").show();
                    $('#node-span-password').show();
                    $('#node-span-token').hide();
                } else if (val === "bearer") {
                    $(".node-input-basic-row").hide();
                    $('#node-span-password').hide();
                    $('#node-span-token').show();
                    $('#node-input-user').val('');
                }
            });

But that handler is only called when you choose another authentication type in the dropdown, but it is NOT called when the config screen opens. So the wrong fields will become visible (i.e. those of basic authentication).

But it can easily be fixed by calling the dropdown's change() function on line 173 of the 21-httprequest.html file:

            if (this.authType) {
                $('#node-input-useAuth').prop('checked', true);
                $("#node-input-authType-select").val(this.authType);
                $("#node-input-authType-select").change();
            } else {
                $('#node-input-useAuth').prop('checked', false);
            }

Then it is solved:

bearer_auth_sol

@knolleary: Nick, do you want me to create a pull request for a single line of code, or isn't that necessary? Thanks, Bart

2 Likes

Pull request please.

Pull request has been created: see here (on master branch).

Thanks for the responses... somehow I got it working this morning... not 100% sure why it wasn't working for me yesterday.
I ran the node red update script two days ago so assumed this would have set me up with the latest version:
https://nodered.org/docs/getting-started/raspberrypi
Instead it only got me to 20.8

What is the recommended way to update to 1.0? I am starting a new project so may as well be on the latest version.

this helped me for my use case - its a workaround - but heck - i ll take it