Where to store sensitive environment variables with Vue3? - vue.js

According to the Vue docs, I can store environment variables in .env files and they are loaded automatically. This works fine but this page says to not store any sensitive ENV variables in these files since they are bundled with the build.
WARNING
Do not store any secrets (such as private API keys) in your app!
Environment variables are embedded into the build, meaning anyone can
view them by inspecting your app's files.
https://cli.vuejs.org/guide/mode-and-env.html#environment-variables
So, if I am developing a webapp that talks to an API that requires an ID and a secret to be sent in order to get a token, where am I supposed to store these ENV variables (CLIENT_ID, CLIENT_SECRET)?
Locally I have an .env.local file that contains these values and I'm also defining them in the Netlify env variables.

Anything secret should be stored only on your server. It should never be part of your Vue app source code no matter how well you think you've hidden it, or encrypted it.
Generally speaking, you should have the user send their username/password, create a token on the server (look into JSON Web Tokens for a lightweight approach) and then either (1) Set it as an HttpOnly cookie (one that javascript cannot touch) or store it in localStorage on the client and set it as a common header in axios (using headers: { Authorization: 'Bearer ' } is fairly common.
Now, the client should be sending back that JWT with every request. So on your server, you can check the JWT is valid, and if so, send back the data requested.

Related

Is it safe to store secrets in nextjs api routes? [duplicate]

I want to build a simple Next.js route that handles payments. In that route's handler I'm commentating with a third-party service via fetch to process a payment. One of the headers is a token (a secure token that should not be visible to anyone). I'm keeping the token in a string variable inside the route handler and using it in the fetch call.
My question is, is this safe? Is the API folder exposed to the front-end like everything else?
Everything added into the api folder will never reach the client side, however is recommended and considered as a good practice to save your sensitive data in .env file
API folder is not exposed on frontend you can safely store the token it will not be visible on frontend
once you add code on you /api folder it will be on server side unless you expose your token through res.send/res.json() or show the source code to other people then they will see your token. if you want you could add your token in environment variables

is there a full Nextcloud API accessable from outside?

I use Nextcloud as a normal user to store and share files.
I decided to use it as a backend for a web application I am developing so that I can store the files in Nextcloud while the frontend is done by me.
I spent some hours on the API docs
https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/index.html
and, with some disappointment, unless I have not made a mistake, I realized that the only API that can be used from outside Nextcloud is the WebDav API.
This is a minimalistic API that allows doing basic things such as uploading a file by passing the full path like with this GET statement (authenticated by basic auth passing username and password in the headers:
GET https://nextcloud.example.com/remote.php/dav/files/username/FolderOne/SubFolderTwo/HelloWorld.txt
This will download the file located in /FolderOne/SubFolderTwo/HelloWorld.txt
with a PUT request, it is possible to overwrite the file by passing the file content in the raw body request
This is very effective but minimalistic.
I was expecting to have a full REST API to access more properties and perform complex operations.
Could you please tell me if I missed some important information?
There is the OCS API but it works only from inside Nextcloud.
Thanks.
A full REST API is avaiable - https://docs.nextcloud.com/server/22/developer_manual/client_apis/OCS/ocs-api-overview.html
Create a Share - https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html
The OwnCloud documentation also offers more examples
https://doc.owncloud.com/server/10.8/developer_manual/core/apis/ocs-share-api.html
You can register an App id and use that to login or passthru a username and password in the authentication header.

How to properly secure Vue using axios and jwt?

I am interested in the theory about properly securing and integrating Vue CLI app with any generic backend framework using JWT.
Let's get straight to the questions:
Is there something like a response Authorization header which the backend can use to set the token automatically in Axios? (I only found a guide to set it manually from the response body)
Does the browser create a new instance of an app if I refresh and/or reopen a tab? Does this mean that the whole app including custom Axios instance with Authorization header is destroyed and the new one needs to set it once again (from local storage)?
Is Axios with (manually) set Authorization header CSRF safe? The point here is that the header isn't browser provided, but rather app provided (only visible to custom Axios instance in the application), right? So an attacker simply cannot get to the token, right?
And so while he can still make a call, it won't get authorized, right?
Short answers:
No you would need to set the Authorization header manually when you get the tokens, jwt is implemented by the client and server, not the browser
If you store jwt in cookies, you don't have to bother about re-setting the authorization header when the page reloads
Only Cookie-based jwt is vulnerable to CSRF exploits

Spartacus Backend OCC login endpoint change

I have a question regarding the possibility to change the backend occ endpoint for the login.
In the default behavior, an auth object is created in local storage.
I changed in the app.module the default login: '/authorizationserver/oauth/token', to a different endpoint (/ourowntestserver/oath/token/test). After the change, the backend-side works as it has before, but on the front-end side, the auth object is not available in the local storage anymore.
In the Spartacus source code I can see an OAUTH_ENDPOINT with the same endpoint '/authorizationserver/oauth/token', used in an open-id-token.service, but I am not sure if that service is responsible for actually saving the token and if I have to extend it in the storefront app along with its store(actions, effects, etc.) too.
Are there any other changes that have to be done for this to work, or am I doing something wrong? Is it possible that the issue could be still back-end related?
Any help would be appreciated. (edited)
I would start by inspecting ngrx actions in devtools. Look for LoadUserToken and LoadUserTokenSuccess and LoadUserTokenFail actions. Look at their payload if everything there looks ok. Maybe the structure of response is different than the one returned from the default hybris OAuth server. Then you might need to create your own effect and handle the response a bit different than we do this by default.
The OAUTH_ENDPOINT is not currently customizable and it is being fixed right now for the 3.0 release. It'll have new auth module structure and allow for easier replacement of OAuth server.
open-id-token.service.ts is only used with Kyma module when you also need apart from access_token the id_token from OAuth server.

Is it good practice or necessary to protect an API with authentication even if the data is not sensitive?

My Vue.js app which interacts with data via a Node.js backend accesses both sensitive and non-sensitive data. I have been able to protect the API's on the Node server, the ones working with sensitive data (such as updating pricing information) using the google authentication API. This requires a user to have to login with a google account before being able to interact with those API's.
I'm now trying to protect the API's which simply retrieve non-sensitive data (such as Names, descriptions, prices of products I sell, etc.) so that even said API's cannot be accessed directly without some form of authentication. ie. If I used something like Postman to retrieve data from the API directly, without authenticating I would not be able to get any data. However, these API's are accessed from a part of the Vue.app which does not require login. ie. Users on the site may see Product, pricing etc. information without having to login first.
In order to protect these "non-sensitive" API's I would have to pass some "secret" such as an API Key from the Vue front-end to the Node backend. I believe from 2 other posts I've done (here and here) that it isn't possible to pass Environmental variables into a Vue App at run-time (I'm using Vue CLI 3). This leaves me with having to hardcode the API Key into the front-end code which means it is no longer "secret" or secure.
I'm in essence trying to do "Application Authentication" but without the ability to pass ENV Variables in Vue at run-time I don't know how to do this securely.
Everything I read on the internet points to either:
Passing ENV Variables into Vue at build-time (which isn't secure in this scenario); or
That I'm missing something for wanting to pass ENV Variables into Vue at run-time in the first place.
Question: Am I overthinking or overcomplicating things by trying to protect data which isn't sensitive?
One way of doing so is the following:
Upon successful authentication generate a JSON Web Token
Send token back to the client (Vue app) and store it in the browser's local storage
On the API route you want to secure add a function that will check whether the the request contains the token you provided on Step 2. You can send the token as part of the request body or maybe a header.
This is a simple yet effective way of securing an API.