How to add token when using axios to send an ajax request? - ajax

I am using Laravel 5.3 and vue.js 2.0,
And I use axios (https://github.com/mzabriskie/axios) to send ajax requests,
I follow the docs to set the TOKEN like this:
<script>
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; //The error is at this line.
new Vue({
el: "#app",
data: function () {
return {
items: []
}
},
mounted: function () {
this.$nextTick(function () {
axios.get('/articles').then(function (response) {
response.data.forEach(function (item) {
item.selected = false;
});
this.items = response.data;
}).catch(function (error) {
console.log(error);
});
});
}
});
</script>
the error in console is like this:
Uncaught ReferenceError: AUTH_TOKEN is not defined
What should I do?

have you set AUTH_TOKEN on the window? If not window.AUTH_TOKEN will naturally not be defined.
A common set up in the head of a laravel app is:
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
This would therefore set the csrf token. I wouldn't imagine this is how you'll be setting an Auth token so you'll probably just need to look into why you are calling window.AUTH_TOKEN
In terms of how you generate your token that is dependant on what type you require but once you have it you may want to look instead at vuex for storing it. Doing so will allow you access to it throughout your app, without having to store anything on the window.

it should be
axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
and you can remove the
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
part

Related

Getting error 401 while fetching data with axios in Laravel

I am trying to fetch some reports with axios in Laravel. I tested it in Postman and everything is fine.
But here I got error 401.
Here is my code:
#Reports.vue file
<template>
<div>
<h1>All reports: </h1>
<div v-for="report in reports" v-bind:key="report.id">
<p>{{ report.description }}</p>
</div>
</div>
</template>
<script>
export default {
name: "Reports",
data () {
return {
reports : [],
}
},
mounted() {
this.fetchReports();
},
methods : {
async fetchReports() {
const {data} = await axios.get('/api/report');
this.reports = data.data;
},
}
}
</script>
#ReportController#index
public function index()
{
$reports = Report::all();
return ReportResource::collection($reports);
}
#api.php
Route::group(['middleware' => 'auth:api'], function () {
Route::apiResource('/report', 'API\ReportController');
});
Thanks in advance. If You need more informations, I will post them.
Laravels auth:api middleware require you to pass Bearer token or ?api_token= url param with your request
Source
And I don't see you passing token with your axios request

Laravel cashier stripe issue with 3d secure cards not redirection to confirmation page

Im struggling to get a Laravel Cashier Strip integration to work with 3d secure cards.
I have go it setup so subscription works and is showing up in my stripe dashboard and everything it getting to my local database.
But when I test with cards that needs strong authntication as 3ds they get the status of incomplete in my stripe dashboard.
I get the cashier.payment response page in my console log. but isn't Cashier supposed to redirect to this confirmation window?
My code is as follows
In my subscription controller i have
public function index() {
$data = [
'intent' => auth()->user()->createSetupIntent(),
// 'plans' => $available_plans
];
return view('artists.subscription')->with($data);
}
public function checkout(Request $request) {
$user = auth()->user();
$paymentMethod = $request->payment_method;
$planId = 'monthly_sub';
// SCA
try {
$subscription = $user->newSubscription('monthly', $planId)->create($paymentMethod);
} catch (IncompletePayment $exception) {
return redirect()->route(
'cashier.payment',
[$exception->payment->id, 'redirect' => route('front')]
);
}
// return response(['status' => 'Success']);
}
and in my stripe js file I have this
const stripe = Stripe('stripe_key'); // i have my test key here
const elements = stripe.elements();
const cardElement = elements.create('card',{hidePostalCode: true});
cardElement.mount('#card-element');
const cardHolderName = document.getElementById('card-holder-name');
const cardButton = document.getElementById('card-button');
const clientSecret = cardButton.dataset.secret;
cardButton.addEventListener('click', async (e) => {
const { setupIntent, error } = await stripe.confirmCardSetup(
clientSecret, {
payment_method: {
card: cardElement,
billing_details: { name: cardHolderName.value }
}
}
);
axios.post('checkout', {
payment_method: setupIntent.payment_method
}).then(response => {
console.log(response.request.responseURL)
})
.catch(error => {
console.log(error.response)
});
});
My blade view is
#extends('layouts.app')
#section('head')
#php
// dd($intent);
#endphp
<script src="https://js.stripe.com/v3/"></script>
<link href="{{ asset('css/stripe.css') }}" rel="stylesheet">
#endsection
#section('content')
<input id="card-holder-name" type="text">
<!-- Stripe Elements Placeholder -->
<div id="card-element"></div>
<button id="card-button" data-secret="{{ $intent->client_secret }}">
subscribe
</button>
#endsection
#section('js')
<script src="{{ asset('js/stripe.js') }}" type="text/javascript"></script>
#endsection
Everything seems to be working but I just get the 3ds confirmation page as a response in my console. How do I get laravel to redirect and open that page for the user?
I think the issue is the order of events, your code should wait for 3DS to be called and completed before calling back to your code after the result is handed back to you. Using this regulator card [1] you should be able to test that with some small changes like this (I had to remove some things but this should be a reference):
stripe.confirmCardSetup(
"seti_xxx", {
payment_method: {
card: card,
billing_details: { name: "Name" }
}
}).then(function(result) {
// Check the result status here!!
axios.post('checkout', {
payment_method: result.setupIntent.payment_method
}).then(response => {
console.log(response.request.responseURL)
}).catch(error => {
console.log(error.response)
});
});
Hope this helps!
[1] https://stripe.com/docs/testing#regulatory-cards

Laravel ajax request returns 500

this is JS code:
<script type="text/javascript">
$(document).ready(function(){
$('#add-more-acadimic').on('click', function(){
$('#add-new-acadimic').modal();
});
$('#SaveAcadimic').on('click', function(){
var name = $('#acadimic').val();
$.post("{{ route('postInsertAcadimic')}}",{name: name},function(data){
console.log(data);
});
});
});
</script>
and this is my route file
Route::post('/manage/course/insert_acadimics', [
'uses' => 'CourseController#postInsertAcadimic',
'as' => 'postInsertAcadimic'
]);
this is controller function
public function postInsertAcadimic(Request $request)
{
if($request->ajax())
{
return response(Academic::create($request->all()));
}
}
and i use csrf token meta tag along with this code in master blade:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}});
and this is the console error:
POST http://localhost:8000/manage/course/insert_acadimics 500 (Internal Server Error) XHR failed loading: POST "http://localhost:8000/manage/course/insert_acadimics".
and this is laravel log error:
[2017-08-06 19:32:42] local.ERROR: exception 'Symfony\Component\Console\Exception\RuntimeException' with message 'Too many arguments, expected arguments "command" "name".' in C:\xampp\htdocs\SMS\vendor\symfony\console\Input\ArgvInput.php:181

Call AJAX with Vue.js and Vue resource in Laravel

I'm making AJAX request in Laravel with Vue.js and Vue resource.
I have view:
{{Form::open(['method' => 'post', 'class' => 'form-inline', 'id' => 'main-form'])}}
{{Form::text('param1', null, ['id' => 'param1', 'class' => 'form-control'])}}
{{Form::text('param2', null, ['id' => 'param2', 'class' => 'form-control'])}}
<input #click="sendIt($event)" type="submit" value="Check prices" class="btn btn-success btn-theme" />
{{Form::close()}}
I have js:
var Vue = require('vue');
var VueResource = require('vue-resource');
Vue.use(VueResource);
Vue.http.headers.common['X-CSRF-TOKEN'] = $('meta[name=_token]').attr('content');
const app = new Vue({
el: '#app',
methods: {
sendIt: function (e)
{
e.preventDefault();
var token = $('[name="_token"]').val();
this.$http.post('/data').then((response) => {
console.log(response);
}, (response) => {
console.log(response);
});
}
}
Route:
Route::post('/data', 'MainController#data');
And controller:
public function data()
{
$msg = $this->test(); //method that retrieves data from db
return response()->json(['msg'=> $msg], 200);
}
It gives me post 500 internal server error
In response I have this headers:
Cache-Control
Content-Type
Date
Phpdebugbar-Id
Server
Status
Transfer-Encoding
X-Powered-By
In network in my data site I have response headers without token, request headers with token and I have token in Request Payload.
If I change method to get I have same error but if I change method to get and if I remove from my controller part of code where I retrieve data from db and just pass string to json (example:
$msg = 'test';
return response()->json(['msg'=> $msg], 200);
I have success and I can output test on page.
So I'm not sure if it's some problem with token or something else.
I tried and this:
var token = $('[name="_token"]').val();
this.$http.post('/prices', {_token:token})
but nothing. Same error again.
If I add this:
http: {
headers: {
X-CSRF-TOKEN: document.querySelector('#token').getAttribute('content')
}
},
I have syntax error on page load.
If I change to this:
http: {
headers: {
Authorization: document.querySelector('#token').getAttribute('content')
}
}
I got internal server error again.
And this is my token in main view:
<meta name="csrf-token" id="token" content="{{ csrf_token() }}">
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
EDIT:
This part works if I add quotes around x-csrf-token but still I have token mismatch error.
http: {
headers: {
'X-CSRF-TOKEN': document.querySelector('#token').getAttribute('content')
}
},
I could be mistaken but in your example at the top you have:
Vue.http.headers.common['X-CSRF-TOKEN'] = $('meta[name=_token]').attr('content');
However, in your main view file you have:
<meta name="csrf-token" id="token" content="{{ csrf_token() }}">
You should be able to simply change $('meta[name=_token]') to $('meta[name=csrf-token]') (so they match).
Furthermore, the reason you had a syntax error with X-CSRF-TOKEN: ... is because you can't use hyphens in key names unless you wrap them in quotes i.e. 'X-CSRF-TOKEN': ....
Hope this helps!

Vue.js resource not working with Laravel 5.3 out-of-box config

Working with fresh install of Laravel 5.3 with Vue.js included and configured out-of-the-box:
this.$http.get(url) returns error:
TypeError: this$1.$http is undefined
Replacing that with Vue.http.get(url)...makes the request but fails to send preflight options:
missing token ‘x-csrf-token’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel
app.js:
require('./bootstrap');
Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('content');
let app = new Vue({
el: '#app',
mounted: () => {
navigator.geolocation.getCurrentPosition((position) => {
app.getZip(position);
});
},
methods: {
getZip: (position) => {
let lat = position.coords.latitude;
let long = position.coords.longitude;
let url = encodeURI(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${long}&sensor=false`);
Vue.http.get(url).then((response) => {
let zip = response.body.results[0].address_components[5].short_name;
console.log(zip);
});
},
},
});
bootstrap.js:
window._ = require('lodash');
window.$ = window.jQuery = require('jquery');
require('bootstrap-sass');
window.Vue = require('vue');
require('vue-resource');
Vue.http.interceptors.push((request, next) => {
request.headers.set('X-CSRF-TOKEN', Laravel.csrfToken);
next();
});
Relevant app.blade.php:
<meta id="token" name="csrf-token" content="{{ csrf_token() }}">
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
<script src="/js/app.js"></script>
gulpfile.js:
const elixir = require('laravel-elixir');
require('laravel-elixir-vue-2');
elixir(mix => {
mix.sass('app.scss')
.webpack('app.js');
});
If I include <script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/1.0.3/vue-resource.min.js"></script> it will successfully make the request with both:
Vue.http.get(url)
this.$http.get(url)
Why isn't this working with the node_module?
require('vue-resource')
Its because you are using require. If you use require you need some library like browserify or webpack, which allows us to have node.js-style modules that compile for use in the browser.

Resources