OAuth2 Microsoft - Single Page Application - Origin header

Hi,

I’m trying to make an OAuth2 connection with Microsoft. We have a Wappler NodeJS with SPA configured as described in this tutorial: https://docs.wappler.io/t/building-spa-pages-with-nodejs/25209

The OAuth2 connection works fine once we configure it as a normal web application, but with SPA configured we eventually get this error:
Tokens issued for the ‘Single-Page Application’ client-type may only be redeemed via cross-origin requests.

Research leads us to these pages where they recommend adding an Origin header. Now i’ve configured CORS but they don’t add these header to the OAuth2 authorize request I think.


Does anyone know how to add this Origin header to the OAuth2 authorize request, or how to handle this error? See my configuration in the screenshots below.

Thanks!

cors

I can try to help here since I’ve been working a lot lately with Microsoft OAuth but I am no expert, only been using Wappler a couple months now.

So the first question is does your NodeJS with SPA setup work with a web application in Azure and not Single-page application or are there issues with using the Web platform?

Based on your screenshots, the OAuth2 office365 should have a space in the Scope Separator. I cannot find the documentation at the moment but Microsoft uses a space for it. I see from your other screenshot that you only have one scope so it may not be needed then otherwise it will error out.

In your next screenshot of your authorize API. Not 100% if its needed but we also included offline_access in the scope. That has been needed in any other system we use it for so we also included it here.

You may have already run across it but this page may help with what you need in regards to SPAs - https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow
and another specifically for SPA - https://learn.microsoft.com/en-us/entra/identity-platform/scenario-spa-overview

You can see the list of accepted parameters on that page, in an example we use the scope parameter to dynamically set a URL so the user automatically logs in and goes to a specific page.

1 Like

Thanks for your reply. Appreciate your help!

My NodeJS application with SPA works with a web application configuration in Azure. So I’ve got it basically working that way.

I’ve tried adding offline_access as it was configured before that way. In the scope separator field I also added a space. Both don’t seem to change anything. The error message remains the same.

I’ve gone through the documentation again, but I can’t get any further. It really looks like I’m missing the Origin header in the OAuth2 request.

While rebuilding the connection with webapplication authentication in Azure and for now not as SPA, we’ve eventually made a small change in /lib/oauth/index.js. We’ve added some code to use a space as the default scope separator, as the scope separator was not used properly and we got the error “invalid_client” because the scopes are indeed separated by commas instead of what we configured.

So we’ve added this code in the index.js in the init() function:

this.opts.scope_separator = ’ ';

We will give it another try with the SPA approach in Microsoft Azure later on.

We also accomplished it with SPA by adding an Origin header to the /lib/oauth/index.js file. We added this line at the bottom of the file and that fixed it:

req.setHeader(‘Origin’, ‘http://localhost:3000’);

@patrick Would this Origin header be a good addition to the code? Could you also have a look at the Scope separator from my previous post. It looks like the Scope separator settings is not used in the NodeJS OAuth function.

Why do you have it configured as a SPA and not Web Application? The SPA is only when your app runs completely on the client using JavaScript. If you use a server action for your oauth2 (which is the default Wappler way) then you need to configure the app as Web Application.

The Origin header is normally set by the browser and can not be overwritten by JavaScript and is used to check the origin of the request to protect against XSS attacks. This is not needed when calling from the server since an attacker normally doesn’t have access to it and can be trusted.

We had it configured as SPA, because we built a web application based on the SPA tutorial from Wappler. No page refreshes are performed when using our web application.

Currently retrieving data via the Azure API works well when we have an access token (configured as web application). We request this once and store it in our database and as long as it is valid we can retrieve data. However, I believe page renewals are required to request and refresh the access token. Or am I wrong?

As long as the OAuth2 Provider is run with an existing access token, we receive data back via the API. When the access token needs to be requested or renewed, we use the OAuth2 Authorize function. However, it gives us a 302 redirect error message.

We actually want to refresh the access token without reloading the page. Is that possible with the web application configuration?

Hey @holyone! You were able to resolve this problem? I’m struggling with that right now.

@patrick, your instructions are helping me a lot, thanks!