How to set up Axios and Nuxt runtime config for multiple APIs? - axios

I've read through all the docs for Nuxt.js environment variables and the Axios module but I'm still quite confused on how to properly set them up for my use case.
I want to query 2 separate APIs:
my own backend with user authentication (e.g. JWT) built with Nuxt serverMiddleware
a public API that requires an account and provides an API key (e.g. TMDB)
My own backend serves as an "extension" of the public API so that I can store additional data for my users.
Now my question is how do I set up my environment variables so that I can safely send dynamic requests to the public API without exposing its private API key? Do I need to use my own backend as a "proxy" and forward client side requests to the public API from there? Or can I directly send requests inside asyncData and fetch when running in SSR mode?
I think I need a general explanation on how Nuxt publicRuntimeConfig and privateRuntimeConfig, and Axios baseURL and browserBaseURL all work together. The docs didn't explain them clearly enough for me.

This question is mixing a lot of stuff at the same time but in no specific order:
you need to run your private call on the server and use privateRuntimeConfig which is available only on the server
fetch() and asyncData() will run both on server and client side (can be forced to be run only on client side with fetchOnServer: false), and it's not a good idea to have those on client since everything there can be publicly seen
if you want to have several instances of axios, a quick search can be helpful to setup this
if you want to use axios in serverMiddleware you'll need to install and import a regular axios since it will be out of the scope of Nuxt
for the most part, if an API is supposed to be used from a front-end you can sometimes use the public API key provided (can be stored in publicRuntimeConfig), if it should remain secret, you'll need a backend to hide it in-between
baseURL is pretty much the default value, browserBaseURL as explained in the docs is mainly an override specific to client-side requests, use it if you need to have something different and that overrides the baseURL one
there are several questions that can be found about how to hide some calls when using an SPA (common question), the incoming edge-side rendering of Nuxt3 may maybe help on this one
one thing to bear in mind is that only the first initial reach to the server will run a server query, everything else will be a hydrated-SPA app meaning that you will not reach back the server after the hydration step (like a MPA Wordpress server would do)

You should send requests only to your private server and it should:
Perform the logic and send the result if it's your custom endpoint
Add API KEY to query and forward the query to the public API if it's public API endpoint.

Related

REST API only accessible through my React client

I'm building a React.js application that will interact with my REST API built in Go.
React will use Javascript Fetch API to send requests to my API.
The problem is I would like to secure my API from being requested from elsewhere. No one should directly be able to access my API either through the URL or through any other client like Postman.
I know what JWT is but this does not solve my problem because anyone can access the token through the browser and then continue to request the API outside the React client using the token.
I have researched extensively but nothing has really fit my description.
Thanks a lot for you help, in advance.
This is an inherently unsolvable problem. React runs on the client. The client controls the code that it executes. Hence, any mechanism you use to restrict the API usage to just your React client will be discoverable and reusable in other client contexts. You cannot control the client, and attempts to do so will be broken if the payoff is valuable enough.
You can attempt to harden it somewhat by using short-term authorization tokens, but there is nothing preventing that token from being grabbed and reused in another context.
If you have to restrict access to an API, you should have a public API which is less dangerous or privileged, and the public API should make use of your private API, effectively proxying the calls to hide the private API, as well as to ensure that only validated queries are executed against the more privileged API.
If you could describe the problem you're trying to mitigate, though, there may be other solutions available.

Should (and how) a backend API used by a frontend UI be secured?

Say you're developing an application which consists of a backend HTTP API, which serves a frontend UI. The UI, upon being rendered on the client's browser, will need to make certain calls to the backend (e.g., fetch data for views). However, all these calls are can be checked on Chrome's developer console, for example. This exposes my application's overall logic and internal API endpoints.
Is this a concern for a web application? I looked around some other websites (e.g., Reddit) and I was indeed able to check an API call was being made and I even managed to reproduce it via cURL, getting the same response back.
My first idea to solve this would be to encrypt all data and have it decrypted internally in the frontend app. However, I don't think this would provide much security since the private key would have to be hardcoded in the app's source code, which can also be checked by modern browsers. Besides, this could greatly impact the application's performance.
The best I could think of was to somehow assign a token (JSON Web Tokens, maybe?) to the session (which in turn is assigned to a user). This token would be needed to make the API calls, and maybe it could have a short expiration time. However, the token can still be seen in the HTTP request.
Any ideas?
I am using bcrypts => https://www.npmjs.com/package/bcryptjs + jsonwebtokens in my MEAN app for the same. Bcryptjs creates a salt at the server side and send an encrypted token to the client. The same token is used for API calls. This makes decoding a bit harder for any phishing attempt.
Use HTTPS instead. => Are querystring parameters secure in HTTPS (HTTP + SSL)?

Secure a REST interface without login

I recently succeeded in building a page that loads data via an ajax get call to a REST interface (that runs on my server) and then uses the data to construct a map overlay for Google maps via JS.
I managed to do this but now I have concerns about the security of my data. Obviously everybody could just use curl to load the overlay data from my REST interface. However, I do not want to make my data so easily available, since they are kind of the business value of my page...
Is saw many solutions on the web that all require a login of the user.
However, this should not be required on my page.
Is there an easy solution to this problem, without the user having to use a log in or something? Basically I only want to allow my web application to query data from my REST interface, but not anyone else.
One solution that came to my head is to pass the data directly from php into JS, when the page is loaded. However this looks like a real ugly solution to me...
On a RESTful interface, I suppose you want to avoid login into a session. You have basically 2 more ways :
use IP address filtering if the web application run on a private network with known IP addresses
pass an identification token in the request headers or as a request parameter. The token has to be passed along in all the requests.

ASP.NET Web API Authentication Options

What options are available for authentication of an MVC3 Web API application that is to be consumed by a JQuery app from another domain?
Here are the constraints/things I've tried so far:-
I don't want to use OAuth; for private apps with limited user bases I cannot expect end users to have their accounts on an existing provider and there is no scope to implement my own
I've had a fully functioning HMAC-SHA256 implemention working just fine using data passed in headers; but this doesn't work in IE because CORS in IE8/9 is broken and doesn't allow you to send headers
I require cross-domain as the consuming app is on a different domain to the API, but can't use jsonp becuase it doesn't allow you to use headers
I'd like to avoid a token (only) based approach, as this is open to replay and violates REST by being stateful
At this point I'm resigned to a HMAC-SHA256 approach that uses either the URL or querystring/post to supply the hash and other variables.
Putting these variables in the URL just seems dirty, and putting them in the querystring/post is a pain.
I was succesfully using the JQuery $.ajaxSetup beforeSend option to generate the hash and attach it to the headers, but as I mentioned you can't use headers with IE8/9.
Now I've had to resort to $.ajaxPrefilter because I can't change the ajax data in beforeSend, and can't just extend data in $.ajaxSetup because I need to dynamically calculate values for the hash based on the type of ajax query.
$.ajaxPrefilter is also an issue because there is no clean/simple way to add the required variables in such a way that is method agnostic... i.e. it has to be querystring for GET and formdata for POST
I must be missing something because I just cannot find a solution that:-
a) supports cross-domain
a) not a massive hack on both the MVC and JQuery sides
c) actually secure
d) works with IE8/9
There has to be someone out there doing this properly...
EDIT
To clarify, the authentication mechanism on the API side is fine... no matter which way I validate the request I generate a GenericPrincipal and use that in the API (the merits of this are for another post, but it does allow me to use the standard authorization mechanisms in MVC, which I prefer to rolling my own... less for other developers on my API to learn and maintain)
The problem lies primarly in the transfer of authentication information from the client to the API:-
- It can't rely on server/API state. So I can't pass username/password in one call, get a token back and then keep using that token (open to replay attack)
- Anything that requires use of request headers is out, because IE uses XDR instead of XHR like the rest of the browsers, and it doesn't support custom headers (I know IE10 supports XHR, but realistically I need IE8+ support)
- I think I'm stuck generating a HMAC and passing it in the URL somewhere (path or querystring) but this seems like a hack because I'm using parts of the request not designed for this
- If I use the path there is a lot of messy parsing because at a minimum I have to pass a username, timestamp and hash with each request; these need to be delimited somehow and I have little control over delimiters being used in the rest of the url
- If I use data (querystring/formdata) I need to change the place I'm sending my authentication details depending on the method I'm using (formdata for POST/PUT/etc and querystring for GET), and I'm also polution the application layer data space with these vars
As bad as it is, the querystring/formdata seems the best option; however now I have to work out how to capture these on each request. I can use a MessageHandler or Filter, but neither provide a convienient way to access the formdata.
I know I could just write all the parsing and handling stuff myself (and it looks like I will) but the point is I can't believe that there isn't a solution to this already. It's like I have (1) support for IE, (2) secure and (3) clean code, and I can only pick two.
Your requirements seem a little bit unjustified to me. You can't ever have everything at the same time, you have to be willing to give something up. A couple of remarks:
OAuth seems to be what you want here, at least with some modifications. You can use Azure's Access Control Service so that you don't have to implement your own token provider. That way, you have "outsourced" the implementation of a secure token provider. Last I checked Azure ACS was still free. There is a lot of clutter when you look for ACS documentation because people mostly use it to plug into another provider like Facebook or Google, but you can tweak it to just be a token provider for your own services.
You seem to worry a lot about replay attacks. Replay attacks almost always are a possibility. I have to just listen to the data passing the wire and send it to your server, even over SSL. Replay attacks are something you need to deal with regardless. Typically what I do is to track a cache of coming requests and add the hash signature to my cache. If I see another request with the same hash within 5 minutes, I ignore it. For this to work, I add the timestamp (millisecond granularity) of the request and some derivative of the URL as my hash parameters. This allows one operation per millisecond to the same address from the same client without the request being marked as replay attack.
You mentioned jQuery which puzzles me a bit if you are using the hashing method. That would mean you actually have your hash algorithm and your signature logic on the client. That's a serious flaw because by just inspecting javascript, I can now know exactly how to sign a request and send it to your server.
Simply said; there is not much special in ASP.NET WebAPI when it comes to authentication.
What I can say is that if you are hosting it inside ASP.NET you'll get support by ASP.NET for the authentication and authorization. In case you have chosen for self-hosting, you will have the option to enable WCF Binding Security options.
When you host your WebAPI in ASP.NET, you will have several authentication options:
Basic Authentication
Forms Authentication - e.g. from any ASP.Net project you can enable Authentication_JSON_AppService.axd in order to the forms authentication
Windows Authentication - HttpClient/WebHttpRequest/WebClient
Or explicitly allow anonymous access to a method of your WebAPI

Browser-based REST api authentication

I'm working on a REST webservice, and in particular authentication methods for browser-based requests. (using JsonP or Cross-domain XHR requests/XDomainRequest).
I've done some research in OAuth, and also Amazon's AWS. The big drawbacks of both is that I need to do either of the following:
Store secret tokens in the browser
Let a server-side script handle the signing. Basically I'd first to a request to a server of mine to get a specific pre-signed javascript request, which I'll use to connect to the real REST server.
What are some other options or suggestions?
Well, the only true answer here is proxying through a server, using sessions/cookies to authenticate and of course use SSL. Sorry for answering my own question.
Yes, jsonp call-authentication is tough, because the browser-client needs to know the shared secret.
An option would be to make the end-point anonymous (no authentication necessary). This comes with other security wholes (server is open for attacks, anyone can call it). But you could handle this by either only exposing very limited resource and/or using rate-limiting. With rate-limiting only a certain number of calls are allowed by one client in a certain range of time. It works by identifying the client (e.g. by source-ips or other client footprints).
I once experimented with one-time tokens, but they all somewhat failed because you have the problem of getting the token itself and protecting multiple retrievals of the token by bots (which comes again to the need of rate-limiting).
I havent tried this myself but you can try the following..(I am pretty sure i will get some feedback)
On the server side, generate a timestamp. Using HMAC-SHA256 an generate a key for that time stamp using a password and send the generated key and time stamp in the html.
When you make the AJAX call to the web service(assuming it is a different server) send the key and the time stamp along with the request. Check if timestamp is within a 5-15 minutes..
if it is do do the HMAC-SHA256 with the same password and key if the key generated is same.
Also on the client side you will have to check if your timestamp is still valid before making the call..
You can generate the key using the following url..
http://buchananweb.co.uk/security01.aspx