Token to authorize an external app NodeJS - node.js

I have a setup of Mongo, Express, ReactJS, NodeJS. My app requires users to log in and then they can do certain actions. Each user get a temporary JWT token.
I want to allow an external WordPress website to send me an array using a POST request.
I've figured out how to do this (using CURL) but my app rejects any requests without a JWT token.
Thing is, I don't want users from WordPress to log in so they have a token. I need a token for the wordpress site. I need some "secret key" so that the WordPress site will be authorized to speak to my app.
So, In my app I created new routes like so:
app.use('/api/external', externalRoutes)
const { getExternalOrder } = require('../controllers/external')
router.post('/', getExternalOrder)
but right now, anyone get send POST to /api/external. So I want to add a "secret key" to make sure it's a verified request.

If the communication between the WordPress site and your application is server-to-server communication; can you use client credential flow where the WordPress site obtains an access token from your IDP using client credentials i.e. client id and client secret...
Other options:
HMAC & shared secret - I've actually done this approach with
WordPress talking to protected external routes.
basic auth
client certificates

Related

Securing a web app against authorization API without revealing credentials

I have a web app MyWebApp.
And two APIs: MyAuthAPI and MyServiceAPI, both RESTful NodeJS. MyAuthAPI uses HashiCorp Vault as a token store with OAuth2.
MyServiceAPI has CRUD operations available to authenticated clients.
There is no human login required (or desired) on MyWebApp. Any human can access MyWebApp through a browser and run the service.
At present, this is the (very insecure) flow:
MyWebApp sends clientid and clientsecret to MyAuthAPI to retrieve token. This token is then used for communicating with MyServiceAPI.
The obvious downside is that anyone can capture the clientid and clientsecret by simply looking in developer tools in a web browser. They could then use those to authenticate with MyAuthAPI, generate their own token, and make calls to MyServiceAPI without MyWebApp being involved.
So how do I best secure the entire application so that MyWebApp is safely and robustly authenticated without revealing the credentials?
Thanks.
ETA:
I want to be able to authenticate MyWebApp with MyAuthAPI and then use the generated token to connect to MyServiceAPI. But I don't want it to be possible that anyone can intercept those credentials - currently they can be see in the request header as "Authorization: Basic "
The MyServiceAPI endpoints must be secured so that only authenticated clients are able to access them. But when that client (MyWebApp) is a public website, how do I authenticate without making the credentials visible?
ETA2:
https://mywebapp.com is MyWebApp which is a React application.
https://myauthapi.com hosts MyAuthAPI
https://myserviceapi.com hosts MyServiceAPI
When I load mywebapp.com in a web browser, it authenticates with myauthapi.com/oauth/token to get a token. At present it does this by sending the creds in the header Authorization: Basic
The token that is returned is then saved.
The web application then tries to get the data from an endpoint on MyServiceApi using this token:
Authorization: Bearer
GET https://myserviceapi.com/objects
or POST myserviceapi.com/objects
or GET myserviceapi.com/objects/objectid
or DELETE myserviceapi.com/objects/objectid
MyServiceAPI verifies the token with MyAuthAPI, but that isn't public-facing, so there's no issue there.
The issue is that, as you can see from the attached screenshot of the Developer Tools console in Chrome, anyone using the web application can see the Authorization header containing the credentials, and could then use these credentials to programatically gain access to the auth API to generate a token which can then be used on the service API endpoints.
I want to restrict all access to the API servers to only come from specific applications, such as MyWebApp, on mywebapp.com.
First, I think this question could better be asked in https://softwareengineering.stackexchange.com/.
Second, where MyWebApp is deployed? How it is being used? If it works with https, then the body is encrypted, and when you send the clientId and clientSecret, you should send it in the body, so users will not be able to see them.
Client Credentials Grant should only be used by confidential Clients. Thats because you can't hide the client_secret on non confidential Clients. Your frontend seems to be a non confidential Client.
Normally you should use the Authorization Code Grant with PKCE. But you would need users to authenticate themselves for that.
Feels like you need an architecture design based on standard flows, since OAuth should work like this:
Web app signs user in via an Authorization Server, using Authorization Code Flow (PKCE)
Web app gets tokens from the Authorization Server
Web app calls API with an access token
API validates token using data from the Authorization Server
API then trusts claims in the access token and uses them for authorization
See my Initial HTTP Messages blog post for an example of how this looks.

How to let frontend know your server has successfully retrieved an access token

I've been studying the OAuth 2.0 authorization code flow and am trying to write a React application with an Express backend that displays what a user would see on their own Instagram profile. I'm trying to do so with minimal external libraries (i.e. not using passport-js) and without bringing a database into the mix.
This is my flow as of now:
Resource owner clicks an <a> tag on the React application (port 3000) which redirects them to the /auth/instagram endpoint of my Express server (port 8000)
res.redirect(AUTHORIZATON_URL) sends them to Instagram's authorization server
Resource owner consents and the authorization code is sent back to the predefined redirect-url /auth/instagram/callback with the authorization code set as a query parameter
I strip the authorization code off the url and make a POST request to https://api.instagram.com/oauth/access_token to grab the access token
Now that I have the access token, how do I reach out to the React frontend to let them know that everything worked and that the user was successfully authenticated?
From what I've read, this is where the idea of sessions and cookies come into play, but I haven't had luck finding documentation on how to achieve what I want without bringing in third party libraries.
In the end, I would like for my app to support multiple users viewing their profiles simultaneously. Since I imagine passing the access token to the frontend defeats the purpose of securely retrieving it on the backend, I'm guessing I will somehow need to pass a session id between the frontend and backend that is somehow linked to an access token.
Any ideas as to what my next steps should be are greatly appreciated, as well as any articles or documentation you see fit. Thanks!
Since you're doing the OAuth authentication on the server side, you have to pass some parameter to the redirect_uri, identifying the user session (see: Adding a query parameter to the Instagram auth redirect_uri doesn't work? );
When the redirect uri is called from the authority server, you will know which user was authorized. To notify the browser there are two options: 1) Notify the client using web sockets; 2) Pull the state from the client using a timer triggered function;

How to authenticated same credentials with wordpress and node

I have two websites, one is wordpress and other is angular/node. How to login wordpress site useing same credentials as angular site. We don't want the user to create another account in wordpress. We should manage this for angular site. How to implemented this scenario.
You can use JSON Web Tokens. The JWT Authentication plugin will allow you to log in from your JS app.
You make a POST request to /WP-JSON/JWT-AUTH/V1/TOKEN with the username and password to get the token (if the credentials are correct), and each time you make a request to the WordPress site you add Authorization : Bearer [token] to your request header.

How to use Passport & JWTs on client-end for authorization?

I'm currently creating a custom CMS for a friend's soccer team. The architecture is as follows:
On the back-end I've an API that interacts with the database (mongoDB).
On the front-end I've an express server that serves the pages using the templating engine handlebars.
Currently I've managed to authenticate requests to the API using Passport and JWTs, which is fine for querying the API, on login I'm storing a JWT with permissions in the cookie storage within the user (it's static pages and not a SPA so I cannot access local/session storage).
My issue is that I am struggling how to implement authorization on the client end for access to the admin panel. Should I decode the JWT on the client-end and read the user role then serve the pages if the admin pages if the user is an admin or should I be sending every request to access the admin section of the front-end to the API for a verification check then serve the files.
Any help would be greatly appreciated, thank you.
I think using a token authentication approach is more suited towards making requests via XHR, rather than hard reloads. The approach you are taking seems to be more suited to a session based authentication strategy. I would use passport-local and authenticate with a user name and password. Once authenticated the user is stored server side in a session variable. You could check the role from that and redirect server side.
If you were to stick with a token you could save it in local storage and then have a script on your admin panel that would first grab the token from local storage and then make a GET request to the server with the token in the header. If the token is valid send back the data to populate the page, otherwise send back an error and redirect from the front end. To get around showing an empty admin panel while checking the validity of the token you could show a loading screen until the request completed.

Making web app with Restful API

I'm making web app using node.js express with Restful API.
And, to use my web app, the user must login. If user doesn't login, he always stays in login page.
But, I heard that restful api doesn't use session or cookie information to maintain user login.
So, I heard that it use JWT. So, I want to use this. But, I saw that it has to compare token information when user access Restful API.
Then, in my case, should the user always have to request token information to the web app server to use my web service? (I mean add token in request header when user request every page)
you can use
HTML Local Storage
When you get JWT token save some value at local storage localStorage.setItem("logenin", "yes");
and check at every page or where you need this infomation localStorage.getItem("logenin");

Resources