I have a route defined in routes.php file but when i make an ajax request from my angular app, i get this error
{"error":{"type":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","message":"Controller method not found.","file":"C:\\xampp\\htdocs\\tedxph\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Controllers\\Controller.php","line":290}}
this is my routes file
/*
|--------------------------------------------------------------------------
| Api Routes
|--------------------------------------------------------------------------
*/
Route::group(array('prefix' => 'api'), function() {
//Auth Routes
Route::post('auth/login', 'ApiUserController#authUser');
Route::post('auth/signup', 'ApiUserController#registerUser');
/* Persons */
Route::group(array('prefix' => 'people'), function() {
Route::get('{id}', 'ApiPeopleController#read');
Route::get('/', 'ApiPeopleController#read');
});
/* Events */
Route::group(array('prefix' => 'events'), function() {
Route::get('{id}', 'ApiEventsController#read');
Route::get('/','ApiEventsController#read');
});
});
Accessing the same url (http://localhost/site/public/api/auth/signup) from a rest client app on chrome does not give any errors, what could be wrong?
this is the angular code from my controller
$rootScope.show('Please wait..registering');
API.register({email: email, password: password})
.success(function (data) {
if(data.status == "success") {
console.log(data);
$rootScope.hide();
}
})
.error(function (error) {
console.log(error)
$rootScope.hide();
})
more angular code
angular.module('tedxph.API', [])
.factory('API', function ($rootScope, $http, $ionicLoading, $window) {
//base url
var base = "http://localhost/tedxph/public/api";
return {
auth: function (form) {
return $http.post(base+"/auth/login", form);
},
register: function (form) {
return $http.post(base+"/auth/signup", form);
},
fetchPeople: function () {
return $http.get(base+"/people");
},
fetchEvents: function() {
return $http.get(base+"/events");
},
}
});
It'd help to see the code you're using to make the angular request, as well as the header information from Chrome's Network -> XHR logger, but my first guess would be Angular is sending the AJAX request with the GET method instead of the POST method. Try changing Angular to send an explicit POST or change routes.php so auth/signup responds to both GET and POST requests.
Update looking at your screen shots, the AJAX request is returning an error 500. There should be information logged to either your laravel.log file or your PHP/webserver error log as to why the error is happening. My guess if your Angular request sends different information that your Chrome/REST-app does, and that triggers a code path where there's an error.
Fixed the problem, turns my controller was calling an undefined method in the controller class.
Renamed the method correctly and the request now works, thanks guys for the input.
Related
So I'm using Jetstream for the authorization part! Now I want to use Laravel sanctum's "auth:sanctum" middleware to protect my api's!
But when I call the api from my SPA, it gives me "401 (Unauthorized)" error even though I'm making csrf-cookie while logging in!
The api works fine when I call it from Postman by passing the token in Bearer token header!
My codes:
Login.vue: (This is where I'm creating the token)
axios.get('/sanctum/csrf-cookie')
.then(response => {
this.form
.transform(data => ({
... data,
remember: this.form.remember ? 'on' : ''
}))
.post(this.route('login'), {
onFinish: () => this.form.reset('password'),
})
})
AppLayout.vue: (This is where I'm calling the api)
axios.get('/api/abilities',)
.then((response)=>{
console.log(response.data);
})
.catch((error)=>{
console.log(error);
})
api.php:
Route::middleware('auth:sanctum')->get('/abilities', function (Request $request) {
return auth()->user();
});
Other things that I've already done are:
Added "axios.defaults.withCredentials = true;" to bootstrap.js
Added "SANCTUM_STATEFUL_DOMAINS=localhost:8000;" to .env file
Added "EnsureFrontendRequestsAreStateful::class" to Kernel.php
I have a problem following this tutorial to implement a simple chat in Laravel using Pusher and Vue.js: link tutorial.
First of all my route in the navbar is this one:
http://localhost/youChat/public/
My web.php file contents the following routes:
Auth::routes();
Route::get('/', 'TweetController#index');
Route::get('tweets', 'TweetController#showTweets')->middleware('auth');
Route::post('tweets', 'TweetController#sentTweet')->middleware('auth');
My app.js file in assets/js where I make the request is this one:
const app = new Vue({
el: '#app',
data: {
tweets: []
},
created() {
this.showTweets();
Echo.private('chat')
.listen('TweetSentEvent', (e) => {
this.tweets.push({
tweet: e.tweet.tweet,
user: e.user
});
});
},
methods: {
showTweets() {
axios.get('/tweets').then(response => {
this.tweets = response.data;
});
},
addTweet(tweet) {
this.tweets.push(tweet);
axios.post('/tweets', qs.stringify(tweet)).then(response => {
console.log(response.data);
});
}
}
});
As you can see I send the request with Axios.
Everything seems looks fine but the GET and POST request are not working. The error in the console inspector shows this:
GET http://localhost/tweets 404 (Not Found)
Uncaught (in promise) Error: Request failed with status code 404
at createError (app.js:13931)
at settle (app.js:35401)
at XMLHttpRequest.handleLoad (app.js:13805)
GET https://stats.pusher.com/timeline/v2/jsonp/1session=Njg3NjQyNDY5NT....MjY1fV0%3D 0 ()
POST http://localhost/broadcasting/auth 404 (Not Found)
And when I try to make a POST:
POST http://localhost/tweets 404 (Not Found)
The get/post should go to this direction:
http://localhost/youChat/public/tweets
but I don't know what's happening. Any suggestion? I'm desperated :D.
Thanks in advance!
You are getting this error because you are using an absolute path.
So either you can store the Base url in a variable or you can use relative path
here is an example.
methods: {
showTweets() {
axios.get('tweets').then(response => {
this.tweets = response.data;
});
},
addTweet(tweet) {
this.tweets.push(tweet);
axios.post('tweets', qs.stringify(tweet)).then(response => {
console.log(response.data);
});
}
}
Remove the / before the URL or
save a
const URL = '{{url('/')}}'
methods: {
showTweets() {
axios.get(URL + '/tweets').then(response => {
this.tweets = response.data;
});
},
addTweet(tweet) {
this.tweets.push(tweet);
axios.post(URL + '/tweets', qs.stringify(tweet)).then(response => {
console.log(response.data);
});
}
}
Hope this helps
Route (web.php)
Route::get('user', function () {
$user=Auth::user();
return response(['user_id'=>$user->id],200);
});
React.js fetch()
fetch('/user')
.then(response => {
return response.json();
})
.then(json => {
console.log(json);
});
When visiting /user in a browser:
{"user_id":1}
When running the fetch() method:
Trying to get property of non-object
This is because $user=Auth::user(); is returning null.
I know this is not a csrf issue because returning static content (such as user_id=>1 ) works fine with the fetch method.
Here are the cookies being sent with the request:
Whats stopping the user session from working? Been messing with this for hours.
Just noticed that my picture shows cookies being returned, not sent.
Changed fetch() code to this and it worked:
fetch('/user',{
credentials: 'include' //Includes cookies
})
.then(response => {
return response.json();
})
.then(json => {
console.log(json);
});
So I am working on an Angular JS x Laravel project. I decided to use JWT tokens and I have some routes like register and login that must be accessible only if the user is not authenticated. Here is are my routes:
Route::group(['middleware' => ['before' => 'jwt.auth']], function () {
Route::resource('api/user', 'UsersController');
Route::resource('api/group', 'GroupsController');
Route::resource('api/project', 'ProjectsController');
Route::resource('api/lesson', 'LessonsController');
Route::get('api/authenticate/user', 'AuthenticationController#getAuthenticatedUser');
Route::get('/{any}', function ($any) {
return view('index');
})->where('any', '.*');
});
Route::post('api/register', 'AuthenticationController#register');
Route::post('api/login', 'AuthenticationController#login');
Route::get('/{any}', function ($any) {
return view('guest');
})->where('any', '.*');
How can I make a route group for the routes outside the jwt.auth route group to be accessible only if the user in not authenticated?
You could do this on the frontend side with your angular controllers. Here is how I did it
//Controller used for the login page
whimAppControllers.controller('LoginController', ['userService', '$location', '$scope', '$http', function (userService, $location, $scope, $http) {
//Upon clicking the login button this function attempts to login in the user through the API
$scope.login = function() {
//Send the user supplied values to the userService in services.js when then attempts to POST to the API
userService.login(
$scope.login, $scope.userName, $scope.password,
//Upon response, if successful return the user to the main page, else return error
function(response){
$location.path('/');
},
function(response){
alert('Something went wrong with the login process. Try again later!');
}
);
}
//Clear out the fields on the login form
$scope.email = '';
$scope.userName = '';
$scope.password = '';
//If the user is already logged, redirect to the main page
if(userService.checkIfLoggedIn())
$location.path('/');
}]);
At the bottom it checks to see if the user has already been assigned a JWT and if so it redirects to the homepage.
In my in my service.js file, the userService has this method to check for the JWT:
//Checks to see if token is present or not
function checkIfLoggedIn() {
if(localStorageService.get('token'))
return true;
else
return false;
};
I'm using LocalStorageModule to make the call to localStorageService:
var whimAppServices = angular.module('whimAppServices', [
'restangular',
'LocalStorageModule',
'ngFileUpload'
]);
I'm using angular-local-storage to store the JWT on the client: https://github.com/grevory/angular-local-storage
okay i've been trying this for like 2 hrs now and cant to make this work. dropzone cant upload any file. the server says "token not provided". im using laravel as backend and it uses jwt tokens for authentication and angular as front end. here's my dropzone config.
$scope.dropzoneConfig = {
options: { // passed into the Dropzone constructor
url: 'http://localhost:8000/api/attachments'
paramName: 'file'
},
eventHandlers: {
sending: function (file, xhr, formData) {
formData.append('token', TokenHandler.getToken());
console.log('sending');
},
success: function (file, response) {
console.log(response);
},
error: function(response) {
console.log(response);
}
}
};
and the route definition
Route::group(array('prefix' => 'api', 'middleware' => 'jwt.auth'), function() {
Route::resource('attachments', 'AttachmentController', ['only' => 'store']);
}));
and the controller method
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store(Request $request)
{
$file = Input::file('file');
return 'okay'; // just until it works
}
the token is correct and is actually getting to the server (because i tried returning the token using Input::get('token') in another controller function and it works). can someone tell me what im doing wrong? im getting "400 Bad Request" with "token_not_provided" message...
thanks for any help. and i apologize for my bad english..
I'm not sure why appending the token to the form isn't working, but you could try sending it in the authorization header instead.
Replace
formData.append('token', TokenHandler.getToken());
With
xhr.setRequestHeader('Authorization', 'Bearer: ' + TokenHandler.getToken());
make sure you add the token to your call: Example you can add the toke as a parameter in your dropzone url parameter.
//If you are using satellizer you can you this
var token = $auth.getToken();// remember to inject $auth
$scope.dropzoneConfig = {
options: { // passed into the Dropzone constructor
url: 'http://localhost:8000/api/attachments?token=token'
paramName: 'file'
},
eventHandlers: {
sending: function (file, xhr, formData) {
formData.append('token', TokenHandler.getToken());
console.log('sending');
},
success: function (file, response) {
console.log(response);
},
error: function(response) {
console.log(response);
}
}
};