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);
});
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 can't figure out why dd(Auth::check()); returns true in Postman but returns false when trying to logout on the browser.
In the header, I'm making a POST request containing the headers required in order for true to be returned in my frontend code - exactly how I'm doing it Postman.
So why's it that it returns false on the browser but returns true in the Postman even though I'm doing the exact same thing?
Any help/tips would be greatly appreciated :)
Here's frontend code:
const logout = () => {
const headers = {
"Accept" : "application/json",
"Authorization" : `Bearer ${localStorage.getItem('token')}`
};
axios.post('http://website.test/api/logout', {headers})
.then(res => {
console.log(res);
}).catch(err => {
console.log(err);
});
};
Here's backend code:
public function logout() {
dd(Auth::check());
}
Here's api.php
Note:
When running dd(Auth::check()); - it always returns false when it's OUTSIDE of the middleware('auth:api');.
However, when running dd(Auth::check()); - it always returns {message: "Unauthenticated."} when it's INSIDE of the middleware('auth:api');.
Route::middleware('auth:api')->group( function () {
Route::post('/logout', [RegisterController::class, 'logout']);
});
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);
}
}
};
im not sure how to do this in laravel. Im trying to do a simple ajax request to my controller. Then in my controller return the values that i sent through so i can console.log the data.
However im having a problem doing so.
Ajax Request:
$.ajaxSetup({
headers: { 'X-CSRF-Token' : $('meta[name=_token]').attr('content') }
});
jQuery.ajax({
url:'/group/create',
type: 'GET',
data: {
name: groupName,
colour: "red"
},
success: function( data ){
console.log(data);
},
error: function (xhr, b, c) {
console.log("xhr=" + xhr + " b=" + b + " c=" + c);
}
});
Route:
Route::get('/group/create', ['middleware' => 'auth', 'uses' => 'GroupController#create']);
Controller:
public function create()
{
$data = Request::all();
return json_encode($data);
}
Now when i console.log the returned data it shows at the exact html for the page im on. Any ideas?
Check on the browser console-network-lastprocess- preview, it could show you the error.
Also you can "console log" from the controller using Log::info('useful information') and it will show it to you at storage/logs/laravel.log
You should use Laravel's JSON return: return response()->json(['name' => 'Abigail', 'state' => 'CA']);
But also what you're doing is actually calling a GET with data however it should be a POST in this case. If you have to provide data to a controller, it's a POST and you can just return the data that way.
So change your AJAX to be POST and then you can use the Request::all() to get all data, and return it via JSON.
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.