“Unauthenticated” when consuming own API with passport? - laravel

I have installed passport as the documentation instructed and added this line the 'web' middleware:
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
and now , Iam trying to get some data using datatable ( datatables.net ) with ajax:
api.php
Route::group(['prefix' => 'v1', 'middleware' => 'auth:api'], function()
{
Route::get('/itemsData', 'DataController#getItemsData')->name('api.getItemsData');
});
in blade:
<script>
$(document).ready(function() {
$('#Table').DataTable({
"order": [],
"processing": true,
"serverSide": true,
"ajax": "{{ route('api.getItemsData') }}",
"columns": [{
"data": "name"
}, {
"data": "created_at"
}],
});
});
</script>
but Iam getting this as a response:
{"message":"Unauthenticated."}

Ok, Passport was looking for 'X-CSRF-TOKEN' which is not in the request header, so It must be added..
so, for this case:
"ajax": {
"url": "{{ route('api.getItemsData') }}",
'beforeSend': function (request) {
request.setRequestHeader("X-CSRF-TOKEN", '{{ csrf_token() }}');
}
},

You need to pass the access_token that you have obtained from Passport in request header as
$.ajaxSetup({
headers: {
'Authorization': 'Bearer ' + 'your access token'
}
});

Related

Laravel Sanctum and Nuxt Js returns Unauthenticated

I recently just deployed my Nuxt Js application and i am having trouble with authentication.
I have set the stateful and session domain in my .env as seen below
SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_DOMAIN=api.example.com
SANCTUM_STATEFUL_DOMAINS=example.com
i also have this in my cors.php
'paths' => ['api/*', 'sanctum/csrf-cookie',],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
In my nuxt.config.js i have the following
auth: {
strategies: {
cookie: {
endpoints: {
csrf: {
url: '/sanctum/csrf-cookie'
},
login: {
url: '/api/login',
},
register: {
url: '/api/register',
},
logout: {
url: '/api/logout',
},
user: {
url: '/api/user',
}
},
user: {
property: 'data'
},
}
},
redirect: {
login: '/auth/login',
logout: '/auth/login',
home: '/dashboard',
},
plugins: [
'~/plugins/axios'
]
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
// Workaround to avoid enforcing hard-coded localhost:3000: https://github.com/nuxt-community/axios-module/issues/308
baseURL: 'http://api.example.com',
credentials: true
},
I do not know what i am doing wrong could someone please help
In your .env file, Change your SESSION_DOMAIN from api.example.com to .example.com
And change your axios baseUrl from http://localhost to your api endpoint

Getting Unathenticated Error NuxtJs Get request

Am trying to do a simple GET request in NuxtJs using Axios. l have configured my nuxt.config.js like this
axios: {
proxy: true,
credentials: true,
baseURL: 'http://localhost:8000/api/'
},
proxy: {
'/api': { target: 'http://localhost:8000', pathRewrite: {'^/api/v1/': ''} }
},
auth: {
strategies: {
laravelSanctum: {
provider: 'laravel/sanctum',
url: 'http://localhost:8000',
token: {
property: 'token',
global: true,
required: true,
type: 'Bearer',
name: 'Authorization'
},
refreshToken: {
property: 'token',
data: 'token',
maxAge: 60 * 60 * 24 * 30
},
user: {
property: 'user',
},
endpoints: {
login: { url: '/api/auth/login', method: 'post' },
user: { url: '/api/user', method: 'get' },
logout: { url: '/api/auth/logout', method: 'get' },
refresh: { url: '/api/refresh', method: 'get' },
},
tokenType: 'Bearer',
tokenRequired: true,
cookie: {
cookie: {
name: 'XSRF-TOKEN',
},
},
}
},
redirect: {
login: '/',
logout: '/',
callback: false,
home: '/'
},
},
router: {
middleware: 'auth'
},
l have tried alot of methods that were posted here before but no avail. Same issues. l also noticed that when l reload the page. Vuex shows user object empty.
Am using Laravel Sactum, any help will be greatly appreciated. Thanks in advance

Filepond: Load default image files

I want to use filepond as my product editor.
How to load current images that is stored on the server? So visitor can decide wheter to change the current images or add a new image.
It's like this form:
=> https://stackoverflow.com/users/edit/{your_user_id}
prefill some data if it has been filled before, but shows nothing when its hasnt been filled before.
I'm mentioning this filepond:
=> https://github.com/pqina/filepond
This is my code on how I show a default image.
const inputElement = document.querySelector('#image');
const pond = FilePond.create(inputElement, options);
pond.setOptions({
allowImagePreview: true,
acceptedFileTypes: ['image/*'],
server: {
process: {
url: 'upload.php',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
},
},
revert: {
url: 'deleteTmpImage.php',
method: 'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
'_method': 'DELETE',
},
},
load: (uniqueFileId, load) => {
fetch(uniqueFileId)
.then(res => res.blob())
.then(load);
},
},
files: [
{
source: 'https://www.example.com/default_image.jpg',
options: {
type: 'local',
}
},
]
});

Problems with ajax of the routing datatable in Api.php with post method

I can not get my DataTable to load the datas by a route in Api.php type POST.
I am using this DataTables: https://datatables.net/
Api.php
Route::post('subredes/{username}/{token}', function($username, $token){
$user = DB::table('usuarios')
->where('token', $token)
->value('username');
$estado = DB::table('usuarios')
->where('username', $username)
->value('estado');
if(!empty(trim($user)) && $estado == 2){
$query = DB::table('subredes as s')
->select('s.id', 's.ip', 's.gateway', 's.mask');
return datatables()
->of($query)
->addColumn('btn','Actions.subredes')
->rawColumns(['btn'])
->toJson();
}
});
Javascript
$(document).ready(function(){
$('#Subredes').DataTable({
"bAutoWidth": false,
"language":{
"url": "{{url('api/spanish')}}"
},
"destroy": true,
"responsive": true,
"serverSide":true,
"ajax": {
"url": "{{url('api/subredes/'.auth()->user()->username.'/'.auth()->user()->token)}}",
"type": "POST",
},
"columnDefs": [{
"targets": 'no-sort',
"orderable": false,
"searchable": false,
}],
"columns":[
{data: 'ip', name: 's.ip'},
{data: 'gateway', name: 's.gateway'},
{data: 'mask', name: 's.mask'},
{data: 'btn'},
]
});
});
Error:
I suspect that it is because he did not give him the CSRF, but I do not know how to do it and I am not 100% sure that this is the problem.
The problem is that DataTables is making a GET request and you only allow POST. The error is in the ajax configuration: You have to replace type with method and it will send it as POST.
Source: https://api.jquery.com/jQuery.ajax/
The CSRF token will be your next problem. The simplest method would be to use GET instead of post (in the DataTables configuration and the Route configuration). Otherwise you will have to expose the token somewhere in your HTML (e.g. a meta tag) and send it with the request:
let token = document.head.querySelector('meta[name="csrf-token"]');
//...
"ajax": {
"url": "{{url('api/subredes/'.auth()->user()->username.'/'.auth()->user()->token)}}",
"method": "POST",
"data": {
_token: token,
},

How to filter for just one customer with yajra datatables

I have a customers table with each record linking to a customer contact:
http://localhost/untdchem/public/home/customers/contacts/1809
When I click on the above link, I want to display all the contacts for customer 1809 only in a datatable. I am trying to pass the customer ID somehow so I can filter for that customer only. I can fill the table with all the contacts but i want to just load for that customer.
Routes:
//Customer Contacts
Route::get('home/customers/contacts', ['as' => 'customers.contacts', 'uses' => 'CustomerContactsController#index']);
Route::get('home/customers/contacts/data', ['as' => 'customers.contacts.data', 'uses' => 'CustomerContactsController#anyData']);
In my controller:
public function index()
{
// GET request to index
return view('pages.customer_contacts.index');
}
public function anyData()
{
$contacts = customer_contact::select(['CustContactFName','CustContactLName','CustContactCountryCode','CustContactExtension','CustContactPhone','CustContactEmail','CustContactType']);
return Datatables::of($contacts)->make(true);
}
In my view:
<script>
$(function() {
$('#customer-contacts-table').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('customers.contacts.data') !!}',
columns: [
{ data: 'CustContactFName', name: 'CustContactFName'},
{ data: 'CustContactLName', name: 'CustContactLName'},
{ data: 'CustContactCountryCode', name: 'CustContactCountryCode'},
{ data: 'CustContactExtension', name: 'CustContactExtension'},
{ data: 'CustContactPhone', name: 'CustContactPhone'},
{ data: 'CustContactEmail', name: 'CustContactEmail'},
{ data: 'CustContactType', name: 'CustContactType'}
//{ data: 'action', name: 'action', orderable: false, searchable: false}
],
order: [[0, "desc" ]]
});
});
</script>
Routes
Route::get('home/customers/contacts/{id}', ['as' => 'customers.contacts', 'uses' => 'CustomerContactsController#index']);
Route::get('home/customers/contacts/data/{id}', ['as' => 'customers.contacts.data', 'uses' => 'CustomerContactsController#anyData']);
Controller
I am assuming there is CustId field that identifies which customer the contact record is assigned to. If your structure is different, adjust accordingly.
public function index($id) {
// GET request to index
return view('pages.customer_contacts.index', compact('id'));
}
public function anyData($id){
$contacts = customer_contact::select([
'CustContactFName',
'CustContactLName',
'CustContactCountryCode',
'CustContactExtension',
'CustContactPhone',
'CustContactEmail',
'CustContactType'
])
->where('CustId', '=', $id);
return Datatables::of($contacts)->make(true);
}
JavaScript
Update the line with ajax option:
ajax: '{!! route('customers.contacts.data', ['id' => $id]) !!}',
The correct solution below:
public function index($CustID = null, Request $request)
{
if ($request->ajax()) {
$contacts = customer_contact::select(['CustContactFName','CustContactLName','CustContactCountryCode','CustContactExtension','CustContactPhone','CustContactEmail','CustContactType']);
if ($CustID) {
$contacts->where('CustID', $CustID);
}
//dd($contacts);
return Datatables::of($contacts)
->addColumn('action', function ($contacts) {
$links="";
$links.='Edit | ';
$links.='<a class="delete" href="'.url('home/customers/contacts/delete', [$contacts->CustID]).'">Delete</a> | ';
return $links;
})->make(true);
}
return view('pages.customer_contacts.index', compact('CustID'));
}
<script>
$(function() {
$('#customer-contacts-table').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('customers.contacts', $CustID) !!}',
columns: [
{ data: 'CustContactFName', name: 'CustContactFName'},
{ data: 'CustContactLName', name: 'CustContactLName'},
{ data: 'CustContactCountryCode', name: 'CustContactCountryCode'},
{ data: 'CustContactExtension', name: 'CustContactExtension'},
{ data: 'CustContactPhone', name: 'CustContactPhone'},
{ data: 'CustContactEmail', name: 'CustContactEmail'},
{ data: 'CustContactType', name: 'CustContactType'},
{ data: 'action', name: 'action', orderable: false, searchable: false}
],
order: [[0, "desc" ]]
});
});
</script>

Resources