How to preserve CORS response headers when throwing exception from a service - servicestack

I am using ServiceStack to build a RESTful API as a backend to a single-page, ajax heavy app.
I have CORS properly configured and everything works as expected.
Some of my services require authorization and throw exceptions that result in 403 or 401 status codes when the user is not authorized, has a expired token, etc. So far so good.
The problem is that whenever I throw one of these exceptions, ServiceStack doesn't include the CORS headers in the response and then the browser refuses to parse it, as it was an ajax call.
Is there a correct way to throw an exception within a service but preserve the CORS headers?
The work around right now is to not throw the exception, set the headers manually and call response.End(). Just think there might be a better way.

Related

Api is working fine with postman but not working in react

Nodejs api is working fine with postman but while i'm trying it with react i'm getting some errors like message: "Request aborted", name: "AxiosError", code: "ECONNABORTED"
I haven't added the authentication yet in my api so that is not needed i guess.
I tried to send it in various ways even i tried to handle preflight problem of cors but not sure if i handled that or not! the api is working with postman absolutely ok response as expected.
make sure you don't pass credentials query params in you get request. if you have added credentials in your get request replace your http method with post.

Axios Interceptors Prevent Error logging into console

Using interceptors for the first time to refresh an expired JSON Web Token. The response interceptor I implemented works successfully in refreshing the token every time, but still logs the error I throw at the server end from the jwt.verify. (I see 403 forbidden each time before token refreshes).
If I'm doing it correctly on the server end and in the client end, should this error even be logging in the browser? I don't want this error to be logging into console. Now I'm thinking I have to refresh the token before it even expires and not even use interceptors.
check the order of responses from the server. Judging by the description, you are not waiting for the generation of a new token. If in JS terms check async/ await sequence

204 error code then 500 error code responses

So I have an application which needs to send data to the API which is created by our team leader using NodeJS with Express.js.
On my end I have laravel application which using VueJS for the UI. Inside the Vue JS component. I am using axios to request to the API.
axios.post('https://clearkey-api.mybluemix.net/sendcampaign', request)
.then(function(response) {
//console.log(response);
})
However, it returns 204 which means according to this https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
204 No Content
The server has fulfilled the request but does not need to return an
entity-body, and might want to return updated metainformation. The
response MAY include new or updated metainformation in the form of
entity-headers, which if present SHOULD be associated with the
requested variant.
If the client is a user agent, it SHOULD NOT change its document view
from that which caused the request to be sent. This response is
primarily intended to allow input for actions to take place without
causing a change to the user agent's active document view, although
any new or updated metainformation SHOULD be applied to the document
currently in the user agent's active view.
The 204 response MUST NOT include a message-body, and thus is always
terminated by the first empty line after the header fields.
Then next it returns 500 Internal Server Error. So in my opinion it returns this error because there is no content to be returned from the server?
Can you tell me other possible problems why it return that response?
Check if the "HTTP method" of the 204 is OPTIONS and if the method of the 500 is POST.
If both are like that, then you are seeing first a CORS pre-flight request (the OPTIONS that returns 204) and then the actual request (the POST that returns 500).
The CORS pre-flight request is a special HTTP message your browser sends to the server when the webpage and the backend are hosted at different addresses. For example, if your website is hosted at http://localhost but the backend you are trying to access is hosted at https://clearkey-api.mybluemix.net.
The reason of the 204 just means your backend endpoint is correctly setup to handle requests for /sendcampaign (you can ignore it). The reason of the 500 is because of some exception in the implementation of the function that handles that endpoint.

Setting Error Pages for a specific path

I am using ECS for a webapp, and i setup an Error Pages definitions for codes 404 and 502. My current setup returns a static maintenance.html file (hosted on S3) and returns a code of 200. I have to return 200, otherwise Outlook (which hosts my app) will not render the returned html, and show an ugly error page instead.
The problem I'm having with it, is that a later API call from my clientside app to my server, might also return 404. With the current setup, CloudFront intercepts this reply, and returns the maintenance.html with code 200. So now my app doesn't know anything is wrong, and later fails on parsing the reply.
Is there a way to define the Error Pages to only handle specific requests? For my usage, I'd like them to only handle calls to my /static/index.html files. If some other file/API call is actually missing from the server, I'd like my client to get the 404, so it can handle it properly.
So to answer your question according to the documentation I read there is currently no way to do this from cloudfront Error Pages Config.
However, We had a similar problem, but in our case API calls were returning a 500 Error with a s3 custom error html instead of the actual server error that I expected only for API calls.
What we ended up doing in this case was a handler in the back end for 500 errors that would return a response code that we were not using in the cloudfront Error Pages if the request Url had the pattern of API calls (we used http Error Code 406) and then the handler will reply with the 406 response code and the whole error instead of the 500 with the s3 response html only when failed over the api url pattern. I know this does not solve the problem the way you would have like to, but probably you may find it helpful until cloudfront allows a custom error response based in a Path Pattern.

Error handling in express based on how a resource is called?

I am using express.
I am handling a Get request like below.
router.get('/user', user.getSessionInfo);
On client side I am using Angularjs.
I want to customize my error handling in nodejs based upon how a resource is being called, i.e. when /user is called via an $http call or directly from browser url so that I can return(if an error happens) either a json error obj or an error page(html).
I tried using req.xhr to decide whether the call is an ajax or not but I am getting false in both cases(not getting X-Requested-With header via $http.get)
So to achieve my functionality Can I depend upon
req.headers['accept'];
as from ajax call it will be
"application/json, text/plain, */*"
and when called from the browser url bar it will be
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
Is my way the best or there is a better way of handling it?
There is another way,use query param(dot extension) to decide resource type:
GET /api/user.json
GET /api/user.html
GET /api/user.xml
and it seems than this solution is more complicated to achieve in Express.
req.xhr was removed in angular. Read here why removed and how to get it back
https://github.com/angular/angular.js/commit/3a75b1124d062f64093a90b26630938558909e8d

Resources