My rejected promise in AUTH_CHECK don't do anything - admin-on-rest

In the AUTH_CHECK of my authprovider i validate my token :
if (type === AUTH_CHECK) {
return isTokenValid(localStorage.getItem('token')) ? Promise.resolve() : Promise.reject()
}
After my rejected promise my resource is called, i can see it in my browser's console :
GET https://localhost:88/api/1/myresource 401
After that, my Login form i s called.
So why calling my resource to detect the unauthorized acces ?
I already rejected my promise before that.

That's because react-admin optimistically renders its UI before the authProvider call returns in order to avoid empty pages

Related

Removing custom error from MessageBag Laravel

I am trying to display a custom error message when the user who is trying to log in isn't registered in my website. I have this code for that.
if (!(User::where('nickname',$request->input('nickname'))->exists())) {
// adding a custom error if user with such nickname doesn't exist
$errors = new MessageBag;
$errors->add('noExist', 'User with such nickname doesnt exist');
return view('login')->withErrors($errors)->with('title','Login');
}
The error prints, but i want to remove it from my MessageBag, so it won't be displayed after a refresh. How can I achieve this?
If you return a view() in a POST method, like the Controller function handling a login attempt, any subsequent refreshes will simply re-submit the form. For this reason, the ErrorBag won't refresh as you'd expect (return to default state). To get around this, use a proper redirect() to handle re-rendering the view():
// return view('login')->withErrors($errors)->with('title','Login');
return redirect("/login")->withErrors($errors);
$errors will be passed from the POST request back to the GET request handling the display of the login view, and on refresh, will be cleared.

Laravel 5.5 Request is empty in Restful controller

I have such a route in my routes/web.php
Route::resource('/api/surveys', 'SurveyController');
As documentation says, it creates all needed routes for API. This is a function, that gets executed when I go for /api/surveys route:
public function index()
{
$request = request();
if(!$request->hasHeader('token')) {
return "No auth token found.";
}
$tokenCheck = $this->userService->isTokenValid($request->header('token'));
if($tokenCheck !== true) {
return $tokenCheck;
}
return $this->surveyService->all();
}
What it does, it checks if token header parameter is set, if not, it returns an error, if yes, it checks if token is valid and etc. if everything is OK, it should return surveys from database.
public function surveys() {
$request = \Request::create('/api/surveys', 'GET');
$request->headers->set('Accept', 'application/json');
$request->headers->set('token', \Cookie::get('token'));
$response = \Route::dispatch($request);
print_r('<pre>');
print_r($response);
print_r('</pre>');
}
I have a website, that should use that API I just created to get all survey records. I create a new request object, set header "token" with token I get from a cookie and then try to dispatch and get a response. But the problem is that everytime I get "No auth token found." error. That means $request->hasHeader('token') returns false, even tough I set it here in my request. If I print_r $request->all() in Restful controller, I get an empty array.
I tried Postman to access this API with token parameter, and it works fine in postman, but here, it seems that Request disappears while it travels to API controller.
What I did wrong here?
When you manually create a request and dispatch it, that works to get the routing to call the correct controller, however that does not affect the request that is bound in the container.
When your "fake" request is handled by the api controller, the request that it pulls out of the container is the original "real" request that was made by the user.
Instead of dispatching the route with your new request, you will need to app()->handle($request) the new request. This, however, will completely replace the original "real" request with your new "fake" request, so everything from the original request will be lost.
Having said all that, this method of consuming your own api is discouraged, even by Taylor. You can read his comment on this Github issue. So, consuming your own api like this may work, but you may also run into some other unforeseen issues.
The more appropriate solution would be to extract out the logic called by the api routes to another class, and then call that extracted logic from both your api routes and your web routes.

Datatables 1.10.5 ajax error handler - Getting access to the http status code

I'm using Datatables 1.10.5 and I have the ajax error handler defined. I need to gain access to the actual http status code when the error fires so I can see if my user's session time has expired (HTTP 401) vs if there's something wrong on the backend such as an HTTP 500 error. Right now the techNote is always 7.
How can I get that elusive HTTP status code from the ajax transaction? I tried below, but it does not fire.
$("#example").ajaxError(function(event, jqxhr, request, settings){
alert("Failure HTTP Code:"+jqxhr.status);
});
and
$.fn.dataTable.ext.errMode = 'throw';
$('#example').on('error.dt', function(e, settings, techNote, message) {
console.log( 'An error has been reported by DataTables: ', message);
});
Does not have the information I need, or at least that I cannot find it in any of the passed variables.
I've been able to get access to the status code without overriding global jQuery ajaxError by overriding the more specific to DataTables $.fn.dataTable.ext.errMode with a function:
$.fn.dataTable.ext.errMode = function (settings, tn, msg) {
if (settings && settings.jqXHR && settings.jqXHR.status == 401) {
window.location = window.location.origin + '/login';
return
}
alert(msg) // Alert for all other error types; default DataTables behavior
};
This example shows a redirect to login on 401 status code, however, you could do the same with any other status code.
Last note is you might want to leverage the DataTables statusCode option for status code specific handling but you'll still need to override $.fn.dataTable.ext.errMode if you want to bypass default error handling since it executes before anything you define in statusCode
Handle xhr event. When Ajax error occurs third argument json would be null and fourth argument xhr would contain jQuery XHR object. You can get the status by accessing xhr.status property.
Also see $.fn.dataTable.ext.errMode which could be used to instruct DataTables not to show the alert.

Redirecting a signal returning an error to another signal

So my use case is that I have an HTTP request (fired using -[NSURLSession rac_dataWithRequest:]) that can return a status code of 403.
When this happens I would like to catch that, and redirect to another SignalProducer that requests an authentication token. When that SignalProducer successfully completes, I would like to redirect back to the original rac_dataWithRequest.
How would I best do this? I'm using ReactiveCocoa 4.x and Swift 2.
do you need to hand the authentication token back to the original request before retrying? If yes, then this won't help you, sorry.
I assumed that you just need to fire the authentication request once and then retry the original request. E.g. your authentication request sets the HTTP Authorization header of your HTTP client so that the next request is automatically authorised...
This gist has the contents of a Playground that illustrates the solution. This gist is the result of me playing around to find a solution, requests are mocked, ...
Lets say you have a SignalProducer for your request:
let request = SignalProducer<Response, NSError> {
// Perform your request that needs authentication here
}
And another one for your authentication request:
let authorize = SignalProducer<Void, NSError> {
// Perform your request that needs authentication here
}
Now you can use flatMapErrors (formerly catch) and retry:
request.flatMapError { error -> SignalProducer<String, NSError> in
if(error.code == 403) {
return authorize.then(SignalProducer(error: error))
} else {
return SignalProducer(error: error)
}
}.retry(1)
So, we catch errors of the original request and, if the error code is 403, we perform the authorize request. Then, we still forward the catched error. Otherwise, we just forward the error.
Forwarding the error after the authorize request is important, otherwise, retry will not restart the original request.
The problem with this however is, that it will retry on every error, not just when the original request returns 403...

How to handle application errors for json api calls using CakePHP?

I am using CakePHP 2.4.
I want my frontend make api calls to my CakePHP backend using ajax.
Suppose this is to change passwords.
Change password action can throw the following application errors:
old password wrong
new password and confirm new passwords do not match
In my frontend, I have a success callback handler and a error callback handler.
The error callback handler handles all the non 200 request calls such as when I throw NotFoundException or UnAuthorizedAccessException in my action.
The success callback handler handles all the 200 request calls including of course, the above 2 scenarios.
My questions are:
Should I continue to do it this way? Meaning to say, inside all success callback handler, I need to watch out for application success and application error scenarios.
Should I send application errors back with actual HTTP error codes?
if I should do 2, how do I implement this in CakePHP?
Thank you.
Don't use http error codes for system errors like:
old password wrong
new password and confirm new passwords do not match
etc etc...
Now using success handler you can show messages and code flow as:
Create Ajax post or get to submit the form, I am showing you post example
var passwordValue = $('#password').val();
$.post( "/updatePassword", { passwordText: passwordValue })
.done(function(response) {
if(response.status === 'Success'){
// Success msg
// whatever
}else{
// Error msg
// whatever
}
});
json response would like:
{
"status": "Failed/Success",
"message": "old password wrong."
}
Create one function in controller
public function updatePassword() {
$myModel = $this->MyModel->find('first' // YOUR CODE LOGIC);
if($this->request->is('ajax') {
$this->layout=null;
// What else?
echo json_encode($myModel);
exit;
// What else?
}
}
Do something like this, hope it will solve your query!

Resources