maintaining session in REST web service - rest

I have a COTS application(PLM application) which has provided few SOAP APIs to access. Since this SOAP API is highly complex, we are developing a easy to use REST wrapper service. Before invoking any API in my COTS application, authentication API needs to be invoked. In my REST wrapper web service, I have a login resource which invokes COTS SOAP login API. To keep things simple for my API users, I store the logged in user details in user session. In every other REST resoruces, I retrieve the session and check whether session has user details. If yes, I proceed and invoke the SOAP API. if not, I return proper HTTP status code. I use Apache CXF for service and client. I mandate my APIusers to maintain the session in the client like this
WebClient.getConfig(client).getRequestContext().put(Message.MAINTAIN_SESSION,
Boolean.TRUE);
In every REST tutorials, it said REST is stateless. I am doubtful whether what I am doing is correct as per REST standards. Please suggest. Thanks

Basically the idea of REST is a stateless interface. However it is common practice to use some kind of authentication for API calls since most of the time not all resources should be public (e.g. the timeline of a twitter user over the twitter API)
Therefore it is ok if you do some kind of authentication and validate a session on further requests (or maybe authenticate with every single request, e.g. with HTTP Basic Access Authentication) to check if access should be granted.
Not part of this and not the idea of a RESTful API would be to store complex session information that would really make the whole thing stateful. This for example includes storage of information of an older request for processing together with one following later.

client.getRequestContext().put(Message.MAINTAIN_SESSION, Boolean.TRUE)
This code causes cookies to be maintained in that specific client only.
If you want those cookies be available in another client, it needs to be programmed.
And if the second client receives additional cookies and you want those cookies available in the first client too, how is that possible?
I need something like a root client that maintains cookies of all sub clients. All cookies must be shared among all clients. Like a shared cookie repository for all clients. Does anyone know how to achieve this?

Related

RESTful API: how to distinguish users requests from front-end requests?

So, I have a RESTful API (built with Hapi.js) that has endpoints consumed by users and my front-end app (built with Next.js). GET api/candies is one of them, I'll take it as an example.
The front-end asks the list of candies stored in my DB and displays them on a page anyone can access (it has to be this way). The front-end doesn't provide an API token since people could read/use it. But, users who want to get this list of candies (to build whatever they want with it) must provide a valid API token (which they get by creating an account on my front-end app).
How could my API tell if a request for api/candies is from a user or from my front-end app, so it can verify (or not) the validity of their token?
I'm wondering if my problem isn't also about web scraping.
Can anyone help me please? :D
I thought about the same problem a while ago. If your frontend has a client side REST client (JS+XHR/fetch), then I don't think it is possible to do this reliably, because no matter how you identify your frontend REST client, your users will be able to copy it just by checking the HTTP requests in browser via CTRL+SHIFT+I. There are even automation tools, which use the browser e.g. Selenium. If you have a server side REST client (e.g. PHP+CURL), then just create a consumer id for the frontend and use a token. Even in this case I can easily write a few lines of code that uses the frontend for the same request. So if you want to sell the same service for money that you provide for free on your frontend, then you are out of luck here. This does not mean that there won't be consumers who are willing to pay for it.
I think your problem is bad business model.
Your requirement can be addressed by inspecting different headers sent by different user agents. You can also add custom headers from your front-end and validate the same on the backend.

How can we determine whether a REST API is stateless or not?

I have implemented REST APIs (GET and POST), my concern is regarding the stateless part of the REST API standard. This is how the APIs are accessed:
The client logs into the application which is hosted on a web portal. The web portal authorizes the logged in user and adds a identifier in the request.
When a request is made to REST API, a filter implemented within the application checks whether the incoming http request header has an identifier associated with it (added by web portal while authorizing).
If header has identifier associated with it, filter passes the request towards the controller.
It would be appreciable if someone could verify whether this design is in accordance with REST stateless principle.
Stateless, in the context of REST, has a very specific meaning
Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.
The classic case of session state leaking into HTTP requests is the use of Cookies.
I don't see anything in your description that leads me to think you are using session context here.

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.

How to protect an API endpoint for reporting client-side JS errors against spam (if even necessary)?

I am developing a web application with Spring Boot and a React.js SPA, but my question is not specific to those libraries/frameworks, as i assume reporting client-side JS errors to the server (for logging and analyzing) must be a common operation for many modern web applications.
So, suppose we have a JS client application that catches an error and a REST endpoint /errors that takes a JSON object holding the relevant information about what happened. The client app sends the data to the server, it gets stored in a database (or whatever) and everyone's happy, right?
Now I am not, really. Because now I have an open (as in allowing unauthenticated create/write operations) API endpoint everyone with just a little knowledge could easily spam.
I might validate the structure of JSON data the endpoint accepts, but that doesn't really solve the problem.
In questions like "Open REST API attached to a database- what stops a bad actor spamming my db?" or "Secure Rest-Service before user authentification", there are suggestions such as:
access quotas (but I don't want to save IPs or anything to identify clients)
Captchas (useless for error reporting, obviously)
e-mail verification (same, just imagine that)
So my questions are:
Is there an elegant, commonly used strategy to secure such an endpoint?
Would a lightweight solution like validating the structure of the data be enough in practice?
Is all this even necessary? After all I won't advertise my error handling API endpoint with a banner in the app...
I’ve seen it done three different ways…
Assuming you are using OAuth 2 to secure your API. Stand up two
error endpoints.
For a logged in user, if an errors occurs you would
hit the /error endpoint, and would authenticate using the existing
user auth token.
For a visitor, you can expose a /clientError (or
named in a way that makes sense to you) endpoint that takes the
client_credentials token for the client app.
Secure the /error endpoint using an api key that would be scope for
access to the error endpoint only.
This key would be specific to the
client and would be pass in the header.
Use a 3rd party tool such as Raygun.io, or any APM tool, such as New Relic.

Client Facing REST API Authentication

I have seen many different posts regarding different solutions for authenticating a RESTful API and I have some questions, given this current scenario.
I've built a REST API that will allow clients of my software service (we are a B2B company) to access resources programmatically. Now that I've got the API working properly, I'd like to secure it in the most standardized way possible. I need to allow access to certain resources based on the caller of the API. That is to say, not all users of the API can access all resources.
I have URLS available in the following formats:
https://mydomain/api/students
https://mydomain/api/students/s123
https://mydomain/api/students/s123/classes
https://mydomain/api/students/s123/classes/c456
So far I've come up with these possible solutions:
Provide a unique key to each client that they can use to ultimately generate an encrypted token that will be passed as a GET parameter at the end of each REST call to (re)-authenticate every single request. Is this approach too expensive
https://mydomain.com/api/students/s123?token=abc123
Provide a value in the HTTP Authorization Header as seen here. Is this almost the same as #1? (Except I can't paste a URL into the browser) Do people use these headers anymore?
Use OAuth 2 (which I'm still a bit unclear on). Does OAuth 2 actually authenticate the client as a logged in user? And doesn't that go against the spirit of a REST API being stateless? I was hoping OAuth was the proper solution for me (since it's a public standard), but after reading up on it a little bit, I'm not so sure. Is it overkill and/or improper for REST API calls?
My goal is to provide an API that will not have to be changed for each client that wants to consume the API, but rather that I can provide a standard documentation made available to all of our clients.
I'll be happy to post additional details if I've been unclear.
There are 2 type of clients you probably want to prepare your API:
trusted clients - Which are written by you. They can have the username and password of the actual user, and they can send that data to your server with every request, possibly in a HTTP auth header. All you need is an encrypted connection by them.
3rd party clients - Which are written by some random developer. You can register them in your service and add a unique API key to each of them. After that if an user wants to use their services, you have to show her a prompt in which she can allow access to the 3rd party client. After that the 3rd party client will be assigned to the user's account with the given permissions and it will get an user specific access token. So when the client sends its API key and the user specific token along with the request, then it sends the requests in the name of the user.
OAuth can help you to control the second situation.
Your URLs do not have a meaning to the clients. By REST you have to decouple the clients from the URL structure by sending links annotated with semantics (e.g. link relations). So your documentation does not have to contain anything about the URL structure (maybe it can be useful for server side debug, but nothing more). You have to talk about different types of links. By generating these links on server side, you can check the permissions of the actual user (or 3rd party client) and skip the links which she does not have permission to follow.