Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic Auth Implementation in Retail React App Take 2️⃣ #732

Closed
wants to merge 1 commit into from

Conversation

johnboxall
Copy link
Collaborator

@johnboxall johnboxall commented Sep 22, 2022

Folks often want to protect their in-progress or non-production storefront from prying eyes.

HTTP basic authentication (same mechanism as storefront protection in B2CE) is one way to do this.

This PR shows how you might approach implementing basic auth.

The big challenge is that both HTTP Basic Auth and SCAPI/OCAPI want to use the Authorization header.

In this attempt, I move the API calls to route through the App Server (ssr.js) rather than proxies, and introduce a "mock" header X-Authorization that I use for all API auth. Ib App Server, I swap the header back before forwarding it to the API origin.

This works great, but we're currently blocked by a bug in aws-serverless-express around duplicate query param handling: CodeGenieApp/serverless-express#214

We use it here:

const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes)

This has since been fixed in that more recent releases of that library.

Blocked by: #733

A demo of this code is deployed here: https://basic-auth-production.mobify-storefront.com/

Username: storefront
Password: password

Note because of the blocking bug, product search doesn't work correctly.

@erilokha-ps
Copy link

Hi @johnboxall this looks like a great progress, thanks.

@bendvc
Copy link
Collaborator

bendvc commented Sep 23, 2022

Nice write up @johnboxall !

Are we looking at any kinds of permanent solutions for this? Off of the top of my head I can think of 2 places were we might want to do that, that is not the PWA-Kit*.

  1. Crazy idea, but how hard would it be able to get SCAPI to support an alternative header for this type of scenario? You used x-authorizaton another example would be application-authoriziation that would be suited for the single-page app landscape. Then we won't need this proxy header swap dance.
  2. Alternatively, but more work, would be using a custom authentication scheme at the runtime level. I imagine the solution manifesting itself as a password protection option set via runtime manager. Once enabled and a password set for a given environment, we trigger a flow in that will prompt the end user for a password and set a cookie that can be used safely with the Authorization header used by the scapi api. (We'd obviously have to wait on environment variables to implement something like that tho).

@johnboxall
Copy link
Collaborator Author

@bendvc

Crazy idea, but how hard would it be able to get SCAPI to support an alternative header for this type of scenario?

I think this is pretty great idea. Let's ask!

Alternatively, but more work, would be using a custom authentication scheme at the runtime level. I imagine the solution manifesting itself as a password protection option set via runtime manager.

The challenge here is that as long as SCAPI/OCAPI/other APIs we're proxying on the same domain want to use the Authorization header, there will be fight. If we solved that problem, then yes, a platform level switch to enable basic auth could work.

I think ideally we'd have some kinda toggle that would require oauth based access, something like https://oauth2-proxy.github.io/oauth2-proxy/ – of which you could say you want auth through Account Manager.

@erilokha-ps
Copy link

erilokha-ps commented Oct 5, 2022

@bendvc

  1. Idea is great, and fits the bill imho, only question would be if Lambda would support/enable end-to-end headers like that (I'm thinking about Ingress)
  2. Again, good thinking, what we did in our implementation is to check whether in env.js object basicAuth exists, and in case it does, trigger auth. Now if we'd like to make that runnable from runtime a flag like 'BASIC_AUTH_DISABLED' could be replaced using simple shell, js, pretty much any script tbf, to search for keyword.

in env.js
... basicAuth: { username: 'superadmin', pass: 'VARIABLE_REPLACABLE_AT_RUNTIME_CI-CD' << this is where it can be replaced with something like 'BASIC_AUTH_DISABLED' }

in ssr.js
if (app.basicAuth.password === constants.BASIC_AUTH_DISABLED) { return next() }

@echessman echessman closed this Jan 10, 2023
@wjhsf wjhsf deleted the example-basic-auth-take-two branch March 17, 2023 16:30
@johnboxall
Copy link
Collaborator Author

Once SalesforceCommerceCloud/commerce-sdk-isomorphic#115 is merged, we should be able to simplify this approach significantly.

Native browser fetch has the ability to disable sending credentials using the credentials: omit option – and we'll no longer have the problem of the Authorization header fight.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants