Hi I am trying to get the passport login working using the bearer token in laravel. the alert shows a token from localstorage.
I have the following javascript code which in the laravel project is in :
/public/js folder:
var token = localStorage.getItem('token');
alert( token );
var jsonp_url = "http://localhost/site1/api/get_data?callback=?"
$.ajax({
method: "GET",
dataType: 'jsonP',
url: jsonp_url,
jsonp: true,
headers: {"Authorization": "Bearer " + token},
success: function(result) {
alert("DATA");
alert(JSON.stringify(result));
},
error: function(result) {
alert("ERR");
alert(JSON.stringify(result));
}
});
then in a external javascript file I include it as follows:
<script src="http://localhost/site1/public/js/api_users.js" type="text/javascript"></script>
The API route in api.php is as follows:
Route::middleware('auth:api')->get('/get_data', function (\Illuminate\Http\Request $request) {
try {
return response()->json([ 'stuff' => 'some data'], '200' )->setCallback($request->input('callback'));
}
catch( \Exception $e ) {
Log::error('Error - ajax_srch_postcode'.$e);
return Response()->json([ 'error' => 'Error cannot proceed!!'], 500 ); // Status code here
}
});
So the code returns a status 200 message but is dropping to the error handler code in the ajax code, rather than the result bit...any ideas??
Related
I want add product to the cart through ajax. only logged in user can add product to the the user. if user is not logged in redirect him to the log in page
Here are my ajax request in blade template
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
function addedToCart(){
var product = $("#productId").val();;
var val = $("#countItem").val();
var unit = parseInt(val);
$.ajax({
type: "POST",
url: "/addtocart",
data: {product: product, unit: unit},
dataType: "json",
success: function (res){
alertMsg.fire({
title: 'Product added to Cart'
})
}
});
}
`
Here the controller code
function addToCart(Request $req){
if($req->session()->has('user')){
$cart = new Cart;
$cart->user_id = $req->session()->get('user')['id'];
$cart->product_id = $req->product;
$cart->unit = $req->unit;
$cart->save();
return response($cart, 201);
}
else{
return redirect('/login');
}
}
It can not go the login route still remain in the same page
Ajax request expects JSON Array Literals, such are JSON formatted array/objects and plain strings, in response. Meaning, you can't make redirect object return in PHP.
You can
// in controller
if (!$req->session()->has('user')) {
return response()->json([
'error' => "Forbidden"
], 403);
}
// save the cart and return success object
Then
// in JS
$.ajax({
type: "POST",
url: "/addtocart",
data: {product: product, unit: unit},
dataType: "json",
success: function (res){
alertMsg.fire({
title: 'Product added to Cart'
})
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
window.location = 'path_for_guests'// this path should be returned from backend for greater security
}
});
Also, be aware of not saved objects. For example, if $cart is not successfully saved you shouldn't return success message. Which is your code doing right now. To follow Object Calisthenics appropriate code (one else it too much), you can use switch and in suitable cases match for various exceptions and expectations like
user session doesn't exist 403
object not created 500
cart created 201
etc
in JSON response you can not use redirect at server side.
either you can play with status here like if the user is logged in, then perform your action, otherwise return a response with status: false.
I have modified your code link below and I have added in comments on what I have changed.
Your JS code
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
function addedToCart(){
var product = $("#productId").val();;
var val = $("#countItem").val();
var unit = parseInt(val);
$.ajax({
type: "POST",
url: "/addtocart",
data: {product: product, unit: unit},
dataType: "json",
success: function (response){
if (response.status) { // if it is true
alertMsg.fire({
title: 'Product added to Cart',
});
} else {
// if it is false, redirect
window.location.href = response.redirect_uri;
}
},
});
}
Your controller function:
function addToCart(Request $request){
if($req->session()->has('user')){
$cart = new Cart;
$cart->user_id = $request->session()->get('user')['id'];
$cart->product_id = $request->product;
$cart->unit = $request->unit;
$cart->save();
return response($cart, 201);
}
else{
// you can return with status flag, and using the redirect_uri your can redirect at your desire page.
return response()->json(array(
'status' => false,
'redirect_uri' => route('login'),
), 401);
}
}
Not sure, about the false status you will get in the AJAX success(), if you will not get then you will have to add the error function after the success(). as we are passing header status in the response.
error: function (error) {
// do console log to check what you get
}
I have a Laravel project and would like the API server to return a message (validation) that will be displayed in Laravel.
Laravel
<script>
jQuery('#ajaxSubmit').click(function(e){
$.ajax({
type: 'post',
url: $("#r").val(),
data: {
i:$("#i").val(),
c:$("#c").val(),
cn:$("#cn").val(),
s:$("#s").val(),
m:$("#m").val(),
},
success: function(response) {
if($.isEmptyObject(response.error)){
location.reload();
}else{
printErrorMsg(response.error);
}
}
});
});
function printErrorMsg (msg) {
$(".print-error-msg").find("ul").html('');
$(".print-error-msg").css('display','block');
$.each( msg, function( key, value ) {
$(".print-error-msg").find("ul").append('<li>'+value+'</li>');
});
}
</script>
API Server
return response()->json(['error' => 'My Message']);
I believe
response.error
must be
response.data.error
So I'm doing an image upload via modal and ajax. It is working, it is saved in the database and saved in public folder as an image, except that the modal does not hide because there's something wrong as said in the console.
statusCode: ƒ ( map )
statusText: "OK"
AJAX:
$(document).ready(function(){
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
//ADD PICTURE
$('#btnUpload').click(function(){
$('#uploadModal').modal('show');
});
$('#btnSave').click(function(){
$.ajax({
data: new FormData($('#uploadForm').get(0)),
url: "{{ route('gallery.store') }}",
type: "POST",
dataType: 'json',
contentType: false, // required for
processData: false, // jquery ajax file upload
success: function(data){
$successmessage = 'SUCCESSFULLY UPLOADED';
$('#uploadModal').modal('hide');
$('#successmessage').text($successmessage);
},
error: function(data){
console.log('Error:', data);
}
});
});
});
CONTROLLER:
public function store(Request $request)
{
$galleries=new Gallery;
// Handle File Upload
if($request->hasFile('upload')){
// Get filename with the extension
$filenameWithExt = $request->file('upload')->getClientOriginalName();
// Get just filename
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
// Get just ext
$extension = $request->file('upload')->getClientOriginalExtension();
// Filename to store
$fileNameToStore= $filename.'.'.$extension;
// Upload Image
$path = $request->file('upload')->storeAs('public/upload', $fileNameToStore);
} else {
$fileNameToStore = 'noimage.jpg';
}
$galleries->description = $request->input('description');
$galleries->upload = $fileNameToStore;
$galleries->save();
}
In store function, you have to return response status code. In the case of success, you return 200.
return response()->json(['success' => 'success'], 200);
In the event of a failure, you return the code that corresponds to the error.
Example:
return response()->json(['error' => 'invalid'], 401);
Whey I login in laravel with ajax , i get success response, and after that i make a get request from the success section by calling a methode to fetch some shops data, then it redirect to the login page (like if I am not logged in)
In postman this works perfectly even weather my routes are inside or outside the auth middleware
( I'm using external single html file instead of laravel views )
Here is my code : 1 - web.php
Auth::routes();
Route::group(['middleware' => 'auth:web'], function () {
Route::get( 'shops/likedshops/', 'ShopUserController#liked_shopes' );
Route::resource( 'shops', 'ShopController', [
'except' => [
'create',
'store',
'edit',
'update',
'destroy'
]
] );
Route::resource( 'shopusers', 'ShopUserController', [
'except' => [
'create',
'show',
'edit',
]
]);
});
2 : ShopUserController.php
<?php
namespace App\Http\Controllers;
use App\Jobs\DeleteDislikedShop;
use Illuminate\Http\Request;
use App\ShopUser;
use App\User;
use Auth;
class ShopUserController extends Controller
{
// ....
public function liked_shopes(){
$user_id = Auth::user()->id;
$user = User::find($user_id);
$shops = $user->shops()->where('is_liked', 1)->paginate(12);
return response()->json(compact('shops'));
}
}
3 : app.js for my html file
$('.form-signin').on('submit',function (e){
var email = $('#email-log').val()
var password = $('#pass-log').val()
e.preventDefault();
login(email, password); // <--------- Login
return false;
});
function login(email, password) {
$.ajax({
method: 'POST',
url: 'http://127.0.0.1:8000/login',
data: {'email': email, 'password': password},
success: function(response){
localStorage.setItem('token', response.success.token);
preferred_shops(); // <--------- Login
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Email and/or Password Incorrect');
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
});
}
function preferred_shops(page_number = 1) {
$('#preferred-shops').remove();
$('#nearby-shops').remove();
$.ajax({
method: 'GET',
url: 'http://127.0.0.1:8000/shops/likedshops',
data: {'page' : page_number},
headers: {"Authorization": localStorage.getItem('token')}, // This isn't helping
success: function(response){
var data = response.shops.data;
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
}
It does not appear that you are sending a CSRF token, see docs below for how to implement this with an AJAX request:
X-CSRF-TOKEN
I get a TokenMismatchException error only when I submit a form with an ajax call? If I don't use an Ajax call I don't get the error.
What is causing this?
Laravel 5.4
I have this in the head of my app.blade.php:
<meta name="csrf-token" content="{{ csrf_token() }}">
My ajax.js
$( document ).ready(function() {
// storing comments
$('#storeComment').on('submit', function(e) {
e.preventDefault();
$.ajax({
method: 'POST',
url: '/comments',
data: {},
success: function(response){
console.log(response);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(JSON.stringify(jqXHR));
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
});
});
});
I also use the bootstrap.js that automatically registers the value of the csrf-token meta tag with the Axios HTTP library. As explained in the Laravel documentation.
Controlle Method:
public function store(CommentRequest $request)
{
$comment = Auth::user()->comments()->save(new Comment($request->all()));
$response = array(
'status' => 'success',
'comment' => $comment
);
return response()->json($response);
}
Add the token to the ajax's data :
$.ajax({
type: 'POST',
......
data: {'_token': '{{ csrf_token() }}'},
........
Instead of calling jQuery you can call Axios directly and have this automatic csrf injection, with the following code:
var data = ['name' => 'Nikola', 'lastName' => 'Gavric'];
axios.post('/comments', data).then(function(response) {
console.log(response);
});
EDIT: Complete example for axios is
$('#storeComment').on('submit', function(e) {
e.preventDefault();
// Retrieve form data
var temp = [];
var data = $(this).serializeArray();
$.each(data, function(index, field) {
temp[field.name] = field.value;
});
// Post request with temp as data
axios.post('/comments', temp).then(function(data) {
console.log(data);
});
});
And this is the code for jQuery, use whichever approach you like better:
$.ajax({
method: 'POST',
url: '/comments',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: {
'name': 'Nikola',
'lastName': 'Gavric'
},
success: function(response){
console.log(response);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(JSON.stringify(jqXHR));
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
});
$.ajax({
type: 'POST',
........
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
...........
});
try this...
Add csrf-token to head of your application :
<meta name="csrf-token" content="{{ csrf_token() }}">
then :
$.ajax({
url: '/some/url',
type: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
success: function(res){
// Your result
console.log(res);
}
});
You can try to disable CSRF verification on specific route in App\Http\Middleware\VerifyCsrfToken.php
protected $except = ['/comments'];