ServiceStack not URL decoding route parameter in RESTful route - urlencode

I'm using self hosted ServiceStack to provide an API to integrate with a ticketing system, and have defined the following routes:
Routes
.Add<TicketsWithStatus>("tickets/{Status}")
.Add<TicketStatusCounts>("tickets");
I'm having URL encoding problems with the first route when the status contains a space. If I browse to http://myservicebase/json/syncreply/TicketsWithStatus?Status=On%20Hold I get the response I'm expecting. However, if I use the RESTful route http://mysevicebase/tickets/On%20Hold I don't get any results.
Debugging my application, I can see that the On%20Hold is being URL decoded to On Hold in the case of the json/syncreply call, but is not decoded when using the RESTful route.
How can I ensure that the status property is properly decoded when calling my service via the RESTful route?

ServiceStack doesn't UrlDecode the PathInfo, it uses the same HttpRequest.PathInfo that the ASP.NET Request object returns. You might have better success if you change it to On+Hold.

Related

Sending xAPI statement to a web application instead of LRS

I have an xAPI content made by storyline I want for the statement to be sent to a webapp instead of the LRS.
this webapp is developped using laravel, and user should be authenticated with email and password to use it.
what I did to send the statement to this app:
1.in the webapp I created an API endpoint route that use POST method.
2.in the xAPI wrapper I changed the endpoint in the configuration to the route I made in the webapp.
const conf = {
"endpoint":"here I added my api endpoint route of the webapp",
"auth":"Basic " + toBase64(""),
}
now whith any interaction with the content where a statement should be sent the request making cors error like in the picture down, I think this is authentication error, how can I add my authentication credentials to the xAPI wrapper?
Your non-LRS LRS is probably not handling preflight requests which are necessary for CORS handling. Most common LRSs will handle those requests appropriately since they expect to be accessed from additional origins. See https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#preflighted_requests
Also note that you'll likely run into issues unless you also handle state requests.
Additionally unless you are requesting the credentials from the user during runtime then hard coding the credentials into the package isn't a great idea from a security perspective.

Auth::user() returns null with the user logged in but works in blade template

I am using Laravel 6 and in the controller store method, Auth::user() returns null even when the user is logged in but works in blade template. I have gone through similar questions but nothing is working.
I am posting to an API route and I am not sure whether this is the reason. Kindly assist.
If you have not adjusted the api web group or the RouteServiceProvider that comes with the default application you will not have any session support in your API routes (routes/api.php). The APIs are usually stateless so no session support. If you want to deal with authentication using the built in authentication system you would want to deal with a token based system. The default api guard that is setup for you will use the TokenGuard which will look in the request for a token being passed to authenticate the user against. You would need to assign the middleware auth with the parameter api, to specify the api guard, auth:api.
If you send a request correctly to one of these end points now, including the token, you will have a user returned from Auth::user() or $request->user() etc.
Laravel 6.x Docs - API Authentication - Passing Tokens in Requests
Laravel 6.x Docs - API Authentication - Protected Routes auth:api
Pleease read the whole section for a better understanding of using this type of Guard with the built in Authentication system:
Laravel 6.x Docs - API Authentication
If you don't want to deal with a "stateless" API, and you would rather use sessions you can just move your API routes to the web.php file and prefix them with api.

WebApi Core 2.2 OData resource/path not found

I'm using WebApi Core 2.2. The Microsoft OData Client is adding a new parent record plus a subrecord (Deal+DealFee) from a WPF application. I'm hosting in IIS on Windows 10.
When I call container.SaveChanges(), it successfully calls the service to add the parent Deal record, but then it does a SECOND POST operation to this url (this is generated by the MS odata client lib):
POST http://localhost/mysite/odata/Deals(14)/DealFees
(note this includes the ID 14 which was just generated when adding the Deal)
This is two separate POSTs from the MS odata client lib, not a "deep insert" apparently. However, this results in a 404 (NotFound), which I can observe in Fiddler. The following urls DO work perfectly:
/odata/Deals
/odata/Deals(14)
/odata/DealFees
It seems like either the WebApi Core 2.2 service is not handling the POST to /Deals(14)/DealFees path, OR /Deals(14)/DealFees isn't a valid odata Uri? Is this kind of path generally supported in OData?
I don't know. Can anyone shed some light on what's going on?
Deep insert is not supported in WebAPI OData as of now. To me, it seems like the client is updating the resource set and the resource set for the navigation with two separate post requests and the reason you are getting a 404 is that there is no action mapped to the second request URI in the service.
The service can support this either by introducing a PostToDealFeesFromDeals controller action with default OData routing convention or use attribute routing to map the action for such requests.
If the action already exists then it might be that the first request did not finish creating the new record and the second request was fired, hence 404.

Passport basic authentication only for API requests

I'm writing an express/node/angular application. When the client-side angular controllers need some data, they request it from the server using an endpoint that returns JSON.
This endpoint is behind some passport.authenticate('local') middleware, however this endpoint is exactly what we need for a public API.
Our API uses a passport.authenticate('basic') (basic http auth).
I'm trying to find a way to use the same URL for both, but I don't want users to my site who aren't logged in to see an http authentication window. I somehow need to tell "is this an API request, or an xhr request from the site"
For example, I want the following URL to work for a locally-authenticated user (would have been authenticated via a /login route) or for an API user:
app.get('/api/v1/tasks', passport.authenticate('basic'), tasks.list);
The only alternative I know of that works is splitting these into two different URLs, one for the site to use internally, and one for the public API. Maybe that's a better strategy for security/organization anyway?

Web API - How to Prevent 404 HTML Response?

How can I change ASP.NET Web API to never return a text/html 404 response? I'd rather it send back XML/JSON with an ExceptionMessage or Message. It doesn't make sense to return HTML from an API, IMO.
Just to clarify, this is for cases when the URL truly is invalid.
Another problem is that I am hosting MVC and Web API in the same project, so I need to respond differently. I am guessing it will depend on whether the URL starts with "api".
You do not get those HTML data if you simply call
throw new HttpResponseException(HttpStatusCode.NotFound);
somewhere in your ApiController's methods.
You get this page only when routing mechanism can't fit your request to any of your ApiController's methods. So the HTML message is attached on the application level not in ApiControllers. Here is very good example how you can handle errors in your ASP.NET application Custom error pages on ASP>NET MVC3.
I would even go further and check if the request comes to WebAPI (not to MVC), and if so redirect to IHttpActionResult in ErrorsContoller.
How to prepare IHttpActionResult for response you can read here Action Results in Web API 2
Have you tried using an Exception Filter? This may allow you to capture exceptions and then set the response type "applications/json", message, etc.