How to use secret keys in Vue app?

Hi there,

I am struggling to find a way to use a secret api key in my Vue application.

I have a Vue app that consumes an (internal) API. The API is behind an API Gateway that is secured by key authentication. For each API request I need to pass the secret api key to authenticate the vue app on the API gateway. As environment variables are embedded into the build, I can’t store secret keys there or anywhere else in the code (obviously).

The only solution I see is to create some sort of proxy on the server that serves my Vue app. Instead of directly calling the API gateway from my app, I instead have to call the endpoint on my server that injects the API gateway key into the request and forwards it to the API gateway. However, this seems as to many steps for a simple API call (App -> Server -> API Gateway -> API -> API Gateway -> Server -> App).

Does anyone have a better solution for my use case or am I misunderstanding anything? Thanks in advance.

@jordib123

  1. Encrypt your API key with JS encryption library, such as crypto.js, AES method, with “secret phrase” outside your app.
  2. Store your encrypted API key in your mobile/web app.
  3. Use input element to type the “secret phrase” in your app - and you can store it to localstorage if you are sure you are the only using the app on your PC/mobile.
  4. Decrypt your API key with the same method AES using the “secret phrase”.
  5. Make API request.

Does it make sense?

1 Like

Hi Pablo,

Thanks for the reply!

My app is a public web application that is used by others without any authentication. In that case your solution does not solve my problem if I am understanding your answer correctly?

I think what you’ve proposed makes sense, however (for obvious reasons) we want to avoid hitting the gateway on every request. So, ideally we have an endpoint that returns the key, likely as a JWT with an expiration. We can the use that JWT with the key for each request until it expires or is refreshed.

So if I understand your use case correctly.

  1. App => Server => API Gateway
  2. Gateway returns JWT
  3. Valid JWT enables us to then go App => API => App

Hopefully that makes sense and can work for you. Obviously I’m not familiar with your system, so I could very much be overlooking some complexities.

1 Like

Hello James,

Thanks for the reply.

Why shouldn’t I be hitting the gateway on every request? Isn’t that the whole purpose of the gateway? A centralized point of authentication, monitoring, logging, management, rate limiting, … Your solution would be indeed an excellent solution if I did not have to call the API Gateway for every request.

Nonetheless I did some more research in the weekend and came to 2 conclusions:

  1. The only way to securely handle private keys is on the server and not on the client. In that case my proposal of passing every api request to the my server first seems to be the only solution.
  2. Just don’t secure the public API. My create/update/delete api endpoints are actually already secured by client id & client secret. But I was looking for some extra layer of security in order that only my web apps can fetch information from the api.

I think for now I am just not going to secure my public API (besides the already implemented client id &
secret authentication on the create/update/delete endpoints).

After re-reading your initial post, you’re right, it wouldn’t be the gateway you’d avoid hitting, it’d be the server. You’d only have to hit it initially to get that JWT.

Hi

I use Vue to query a NodeJS back end via an HTTP call which should be no different to calling a gateway - you would probably just want to use HTTPS. If you are using say axios to do the HTTP call then you may need to send the token in the Authorization header

Depending on the authentication method used by the gateway there should be function to call to get the access token that is returned after a successful login.

HTTP.defaults.headers.common[‘Authorization’]=Bearer ${await this.$auth.getAccessToken()}

const response = await HTTP.get(./MyEndPoint/${this.Id} )

I am no expert on internet security but I believe the guidelines are that local storage should not be used for anything security related. We only use it to store the users’ last selections to save them having to reselect every time.

There is a lot more detail behind this but I suggest you check on the authentication method being used by the gateway.

Regards

Paul