# Custom Authentication/storing own token

**URL:** <https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006>\
**Category:** Feature Requests\
**Created:** [26 February 2022 04:37 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006 "2022-02-26T04:37:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ArFe](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/arfe/32/57427_2.png) [@ArFe](https://discourse.nodered.org/u/ArFe)\
**Post date:** [26 February 2022 04:37 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/1 "2022-02-26T04:37:41Z")

</div>

Hello,

I have the same needs of this person:

> [@Custom Authentication And Replacing Application Tokens](https://discourse.nodered.org/t/custom-authentication-and-replacing-application-tokens/37508/6):
>
> Yes, I get this. I had success in implementing the same too. Now I want to use the same token for my front end to use in my custom nodes to authenticate to another API which will return the JSON payload for the drop-down I had built in the custom node. If I pass the token I can pretty much access the same using localStorage.getItem("auth-tokens"))["access\_token"] How can I do the same when I pass the User Name and Password? I mean when I pass the User Name and Password and authenticate to the …

We have two different UIs. One for the entire system and Node-RED.  
Basically, the idea is to delegate the authentication entirely to an external API (same that works for the main UI).  
That way, if you come through the main UI, or login via Node-RED, you end up with the same token and authentication methods.

There are 2 possible flows, i.e:

1 - `noderedwebserver:1880/?access_token=<ACCESS_TOKEN>`  
token gets check via `settings.adminAuth.tokens()`

2- `noderedwebserver:1880` --\> login via Node-RED editor  
Credentials get checked via `settings.adminAuth.authenticate()`  
A token is received (from the external API) and returned back via `settings.adminAuth.authenticate()` resolve(possibly) for subsequent checks via `settings.adminAuth.tokens()`

All that is needed is to store the token when the `settings.adminAuth.authenticate()` resolves. I'm not entirely sure, but it should be possible to send a token together with username and permissions, that then get stored (on `localStorage.auth-tokens`) instead of the Node-RED token, and used in `settings.adminAuth.tokens()`.

I'm willing to make the changes myself, if possible, with a little guidance. It should not be a breaking change, as if the return from `settings.adminAuth.authenticate()` resolves no token, life goes on as it is today.

Thanks for your help and guidance.

---

<div class="post-metadata">

**Author:** ![ArFe](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/arfe/32/57427_2.png) [@ArFe](https://discourse.nodered.org/u/ArFe)\
**Post date:** [26 February 2022 15:39 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/2 "2022-02-26T15:39:50Z")

</div>

Yesterday I tried it out and the solution seems fairly easy, and non-breaking.

What I've done is returning a token with user, on `settings.adminAuth.authenticate()`

```auto
    const user = { username: "admin", permissions: '*', token:token };
    resolve(user);

```

Then, I changed  
`node-red/packages/node_modules/@node-red/editor-api/lib/auth/strategies.js`  
`-> Users.authenticate(username,password)` function to check for the token. If found, call done with the `user.token` instead of calling `Tokens.create()`.

In addition, this solution is future proof, if you decide to change where the token is stored (since @knolleary mentioned this was something they would planning on changing in the near future), as it uses the same mechanism to save the token as it is done today.

Please let me know if this could be a solution so I can work on it, test it more, and open a PR.

Thanks

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [26 February 2022 15:40 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/3 "2022-02-26T15:40:09Z")

</div>

> [@ArFe](#):
>
> We have two different UIs. One for the entire system and Node-RED.  
> Basically, the idea is to delegate the authentication entirely to an external API (same that works for the main UI).

There is a very easy way to do this without needing any changes to Node-RED. Use an external reverse proxy to do the authentication. I've been writing some documentation on using NGINX to do this recently and I've already shared drafts in this forum. My doc is aimed at uibuilder but it equally works for any Node-RED installation along with Dashboard, uibuilder and other non-NR web apps.

---

<div class="post-metadata">

**Author:** ![ArFe](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/arfe/32/57427_2.png) [@ArFe](https://discourse.nodered.org/u/ArFe)\
**Post date:** [26 February 2022 15:49 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/4 "2022-02-26T15:49:55Z")

</div>

> [@TotallyInformation](#):
>
> > [@ArFe](#):
> >
> > We have two different UIs. One for the entire system and Node-RED.  
> > Basically, the idea is to delegate the authentication entirely to an external API (same that works for the main UI).
> 
> There is a very easy way to do this without needing any changes to Node-RED. Use an external reverse proxy to do the authentication. I've been writing some documentation on using NGINX to do this recently and I've already shared drafts in this forum. My doc is aimed at uibuilder but it equally works for any Node-RED installation along with Dashboard, uibuilder and other non-NR web apps.

Thank you, I've seen your comments in the past and given some thought to it.

This is a different approach to what we are trying to achieve, and it seems natural for Node-RED to work the way I'm proposing.

- You can authenticate via external API with user/pass.
- You can validate a token via external API.
- But you **can't** save your token when you authenticate via external API, so you can then validate the token via external API.

IMO, it's just a part of Node-RED that is missing, although there are other (maybe better?) ways to put your system under token/password protection.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [26 February 2022 16:14 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/5 "2022-02-26T16:14:27Z")

</div>

> [@ArFe](#):
>
> since @knolleary mentioned this was something they would planning on changing in the near future

It's something that we know needs improving, but I'm unlikely to be able to dedicate time to figure out the necessary changes as I don't have a personal use for it.

If you wanted to propose a PR with an explanation of what it enables that would be welcome.

Please target the dev branch.

---

<div class="post-metadata">

**Author:** ![ArFe](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/arfe/32/57427_2.png) [@ArFe](https://discourse.nodered.org/u/ArFe)\
**Post date:** [26 February 2022 16:19 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/6 "2022-02-26T16:19:14Z")

</div>

Thanks, will do.

To be clear, my proposal is for storing user Token instead of Node-RED own token when needed, not to tackle the _where to store the token_ (which is a different story entirely).

---

<div class="post-metadata">

**Author:** ![ArFe](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/arfe/32/57427_2.png) [@ArFe](https://discourse.nodered.org/u/ArFe)\
**Post date:** [26 February 2022 23:33 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/7 "2022-02-26T23:33:53Z")

</div>

PR opened:

> <https://github.com/node-red/node-red/pull/3460>
>
> \<!--
> \## Before you hit that Submit button....
> 
> Please read our \[contribution …guidelines\](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
> before submitting a pull-request.
> 
> \## Types of changes
> 
> What types of changes does your code introduce?
> Put an \`x\` in the boxes that apply
> \--\>
> 
> \- \[\] Bugfix (non-breaking change which fixes an issue)
> \- \[x\] New feature (non-breaking change which adds functionality)
> 
> \<!--
> If you want to raise a pull-request with a new feature, or a refactoring
> of existing code, it \*\*may well get rejected\*\* if it hasn't been discussed on
> the \[forum\](https://discourse.nodered.org) or
> \[slack team\](https://nodered.org/slack) first.
> 
> \--\>
> 
> \## Proposed changes
> 
> 
> 
> As discussed \[here\](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/4), this proposed change aims to close the loop for authentication with external APIs.
> 
> Currently:
> 
> 1. You can authenticate via external API with username and password.
> 2. You can validate a \_token\_ via external API.
> 3. But you \*\*can't\*\* save your \_token\_ when you authenticate via external API, so you can then validate the \_token\_ via the same external API.
> 
> This feature adds the possibility for number 3, where you can return a \_token\_ with your user and it gets stored instead of the Node-RED generated \_token\_.
> 
> Here is an example of how to use it (this would be placed on settings.js):
> \`\`\`
> adminAuth: {
> ...
> authenticate: function(username,password) {
> return new Promise(function(resolve) {
> // Do whatever work is needed to validate the username/password
> // combination, and receive/generate a token.
> if (valid) {
> // Resolve with the user object. Equivalent to having
> // called users(username);
> var user = { username: "admin", permissions: "\*", token: token };
> resolve(user);
> } else {
> // Resolve with null to indicate the username/password pair
> // were not valid.
> resolve(null);
> }
> });
> },
> ...
> }
> \`\`\`
> 
> Then you can use the \`adminAuth.tokens()\`to validate your \_token\_ as usual.
> 
> Furthermore, this addition is future proof, and it just replaces the token generation before it happens. This means if it's decided to change where the \_token\_ is stored, it will not impact this solution.
> 
> \## Checklist
> 
> 
> \- \[x\] I have read the \[contribution guidelines\](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md)
> \- \[x\] For non-bugfix PRs, I have discussed this change on the forum/slack team.
> \- \[x\] I have run \`grunt\` to verify the unit tests pass
> \- \[x\] I have added suitable unit tests to cover the new/changed functionality

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [27 April 2022 23:34 UTC](https://discourse.nodered.org/t/custom-authentication-storing-own-token/59006/8 "2022-04-27T23:34:02Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
