Vue API Calls and Laravel Middleware - laravel

Is it possible to globally set a listener on API calls made with Axios in Vue? The Laravel back-end has middleware set up on each endpoint that will either give the requested data or return a message saying that they need to check their messages. My goal is to capture that message and redirect the user to the page to view their message. I can't think of a way to do this other than setting something on each function that checks for the message and responds accordingly. There are hundreds of functions and that it wouldn't be a clean solution.
Any and all recommendations are welcome!

Using Axios Interceptors you can do something along these lines:
this.$http.interceptors.response.use(response => () {
// Redirect to a new page when you send
// custom header from the server
if (response.headers.hasOwnProperty('my-custom-header')) {
window.location.href = '/another-page';
}
// Or when you get a specific response status code
if (response.status === 402) {
window.location.href = '/another-page';
}
// Or when the response contains some specific data
if (response.data.someKey === 'redirect') {
window.location.href = '/another-page';
}
// ...or whatever you want
});

Related

Vue router navigation guard prevent url from being changed

I'm using a vuejs navigation guard to do some checks to check if a user is valid to enter a page. If the user doesn't meet the criteria I want the auth guard to return false which it currently does. However, when this is done the browser url gets set back to the previous url I came from. I don't want this behaviour instead I want the browser url to stay the same but still keep the user unable to use the page.
The reason I want this is because when the user hits refresh I want it to stay on the same page. I know this is intended vuejs behaviour for the router but I'm hoping to find a way around it. Here is the code for auth guard.
function guardRoute (to, from, next) {
if (window.$cookies.get('kiosk_mode') === new DeviceUUID().get()) {
return next(false)
}
return next()
}
To reject a navigation but to not reset the url to its previous state you can reject the navigation with (requires vue 2.4.0+):
next(new Error('Authentication failure'));
And if you don't have router error handling then you need to include:
router.onError(error => {
console.log(error);
});
See documentation for more details: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards
Try this
history.pushState({}, null, '/test') before the return next(false);

axios get passing parameter to laravel route

I am trying to pass an id through axios.get in vue.js to laravel route.
my axios code plus parameter are as following,
axios.get('http://localhost/laravel_back/public/api/bpaper',{
params: {
id:12
}
and my laravel route is as follows,
Route::get('bpaper/{id}', function($id)
{
return 'Paper '.$id;
});
when executing this code i get a 404 error on my browser console. and the request url is,
Request URL:http://localhost/laravel_back/public/api/bpaper?id=12
I have already given the access-control allow methods to allow communication through axios. And the code runs when not providing a parameter. any one know a fix.
Considerind server-side is Route::get('bpaper/{id}', function($id) { ..., the id is part of the path, not a parameter. Add it to the URL. Do:
var myId = 12;
axios.get('http://localhost/laravel_back/public/api/bpaper/' + myId)
Added it to a myId variable for clarity, you don't have to do it. Using:
axios.get('http://localhost/laravel_back/public/api/bpaper/12')
would work just as well.
Also, if you have access to newer versions of JavaScript, you can profit from template strings:
var myId = 12;
axios.get(`http://localhost/laravel_back/public/api/bpaper/${myId}`)

Session Expire Symfony 2 Ajax

My application uses ajax to request data. I'm using Symfony2, and when the session expires and I make a request with ajax, the login form is shown inside the main area on my application, and not as another view as should be. How can solve this problem. Thanks
I would suggest creating event listener which will be listening for every request:
services.yml:
your_request_listener:
class: Acme\AppBundle\EventListener\RequestListener
arguments: [#security.token_storage]
tags:
- { name: kernel.event_listener, event: kernel.request, method: onRequest }
In this event listener I would check for type of request so this would be only Ajax request listener. When request is ajax type then I would check if session has expired - if so, I would create response which will be valid response for ajax request (i.e. JsonResponse) and set this response to be sent to user.
class RequestListener
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function onRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->isXmlHttpRequest()) {
return; //we dismiss requests other than ajax
}
//now you check if user is authenticated/session expired/whatever you need
$token = $this->tokenStorage->getToken();
if ($token === null) {
//now you create response which you would expect in your js doing ajax, for example JsonResponse
$response = new JsonResponse(); //you should give some content here
$event->setResponse($response); //now you override response which will be sent to user
}
}
}
You could use an entry point in which you verify if the request is an AJAX request. If yes, you return a JSON response with 401 HTTP status code. Then in JS code you verify the HTTP status code. If 401, then redirect to login page.
You can read my post here with the complete solution (see my own answer to my own question). This solution is based on this excellent post.

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!

Debugging Ajax requests in a Symfony environment

Not sure if SFDebug is any help in this situation. I am making an ajax post using jQuery. Which retrieves JSON data in my action URL and then makes a call to the Model method that executes the action. The part until my action URL, and the jQuery call to it work fine. With the data transmitted from the client to the server well received and no errors being made.
It is the part where it calls the method on the Model that is failing. My jQuery method looks like this:
$.post(url, jsonData, function(servermsg) { console.log(servermsg); }) ;
My server action is like this
public function executeMyAjaxRequest(sfWebRequest $request)
{
if($request->isXmlHttpRequest())
{
// process whatever
$servermsg = Doctrine_Core::getTable('table')->addDataToTable($dataArray);
return $this->renderText($servermsg);
}
return false;
}
The method of concern in the Table.class.php file looks like this:
public function addDataToTable($dataArray)
{
// process $dataArray and retrieve the necessary data
$data = new Data();
$data->field = $dataArray['field'];
.
.
.
$data->save();
return $data->id ;
}
The method fails up here in the model, when renderText in the action is returned and logged into the console, it returns the HTMl for SFDEBUG. Which indicates that it failed.
If this was not an Ajax call, I could debug it by seeing what the model method spat out, but this is a little tedious with Ajax in the mix.
Not looking for exact answers here, but more on how I can approach debugging ajax requests in a symfony environment, so if there are suggestions on how I can debug this, that would be great.
You must send cookie with session ide key via ajax
(Assuming you have XDEBUG configured on the server)
In order to trigger a debug session by an AJAX request you have to somehow make that request to send additional URL parameter XDEBUG_SESSION_START=1. For your example:
$.post(url + '?XDEBUG_SESSION_START=1', jsonData, function(servermsg) { console.log(servermsg); }) ;
You can also trigger it via cookie, but appending URL parameter usually easier.

Resources