Accessing server.private setting in client without revealing it, is it possible?

Hi all,

Meteor + React App. I’m using NPM UI package on client, which requires auth by API key, which MUST be hidden from public. I’m completely stuck. Is there a way to use secure data (api keys, tokens) with Meteor similar to what .env file providing for React Projects, below how it used in react:
const apiID = process.env.REACT_APP_API_ID and apiId seems not available to browser.

Using Meteor Methods will not work, as it will reveal it to browser anyway. Any suggestions from Meteor Docs don’t work.

The NMP package does not provide server import for auth nor it offers dynamic token, API key must be include with function call.

Any ideas?

I’m at the stage of moving from Meteor to MERN stack.
Will appreciate any suggestions.

Thanks.

You will need to use Meteor settings environment variables.

You may want to check this article which is still relevant.

Hi,
Thanks for providing the link, but it is the same as described in Meteor Docs, just easier read, and will not help in my case.

See how this works? Again, anything that’s stored in our parent object will be accessible **on the server only.** Ever. To make sure values we don’t need to be terribly secure with are available on the client, we must nest values inside of the "public": {} object.

What is stored in ‘private’ section of the settings file only accessible on the server. On another hand, ‘public’ section will not hide any sensitive data on the client.

The npm package I use, unfortunately doesn’t have server exports, so only accessible on the client, and in props taking API key, token, etc.

With React I can just simple use .env file which is secure and not exposed to the browser, but any environmental settings are accessible on the client without expositing its value.

I failed to find similar approach for Meteor. Suggested in the Docs: https://guide.meteor.com/security.html#secret-code
ValidatedMethod still exposing its value to the browser, easily seen in any debug tools.

Here is part of the code where API key is used on client:
await client.join("API Key","API token").....

Thanks.

If the API key is required on the client there is no such thing as private. You can store it on the server and send t via Method to the client by once it’s there, it could leak according to Mr. Murphy.

What I don’t understand is, how your .env solution would differ from that. Is this package maybe built with server-side-rendering in mind?

2 Likes

I have a feeling that its not secure with .env either, but this article claims otherwise:

If I was an owner of npm package I would use dynamic keys on client, which generated on the server using the hash salt.

I’m puzzled with the article as well, how would the react component hide the API key once rendered to the client, I don’t see a way where this can be secure at the client? since all the client code is shipped and executed at the browser, so usually you would make those calls at the server if you want it secure.

1 Like

Looks like it doesn’t, I have debugged production JS and API key was visible in the code. I’m not sure why devs decided to use .env file in the demo app, but it is definitely not hiding anything.

Without server component of the same npm, its impossible. Thanks for all your input.

As you have already discovered, this is a falseism.

Yes, I have. Very surprised that many articles claim this is the way to hide API key or any other sensitive info, and none otherwise.

I read the article and it’s using .env in the back end so the the API keys are used before the react code is rendered and send to the client (server side rendering).

It is used in “back-end”, not on the server side, as per article; but back end can also expose the key to public, depends on the project, some has thousands of users using their backend.

From the article:

import React, { Component } from 'react';
import './App.css';
console.log(process.env.REACT_APP_GOOGLE_API_KEY)
class App extends Component {
...

This is a client, not server side rendering.

After reading tons of different articles, docs, manuals, I still don’t know what is the best approach to use API keys with Meteor/React apps? The only thing comes to my mind is to encode it with hash salt or other on the server and decode on the client. But this approach must be supported by API supplier.

Since you have your own backend, one of the best approaches would be to create a middleware (I recommend this brilliant NPM package for that https://github.com/chimurai/http-proxy-middleware), and rewrite the URL dynamically, adding the API key at request time.

The middleware is plug and play in Meteor. Then you just call that route from the frontend client instead of calling said API.

1 Like

Thanks. I’ll see if I can use it for this.

It must also be unique across all clients that the authorization server handles.

1 Like

Then on the server you query Mongo for that particular user and use the API key stored for that user. You could cache the result in memory for the next request, to save you repeating the queries, if your latency is high.

1 Like