Laravel passport api/user route is unauthorized - laravel-5

Im using laravel passport for token authentication, and axios for send requests from vuejs frontend. I can successfully login usin oauth/token url and it does return access token, refresh token and other data. But when every time i trying to access api/user route it returns me unauthorized error message. It seems bearer token is not in header but i cannot insert that token to axios header in bootstrap.js it also return error. Can anyone help.

You can do like ,first create an axios instance with token
const HTTP = axios.create({
baseURL: `http://baseURL.com/api`,
headers: {
Authorization: 'Bearer {token}'
}
})
Then you can use that 'HTTP' constant can be in your script to call the request
created() {
HTTP.get(`user`)
.then(response => {
})
.catch(e => {
this.errors.push(e)
})
}
Refer more here to how to work with axios

Related

Axios not sending XSRF token with headers

I am integrating a Vue JS (Quasar framework) based SPA with API. The API is built in Laravel and is using sanctum for CSRF.
When I send a request to the sanctum endpoint https://someweburl.com/sanctum/csrf-cookie it sends the XSRF-TOKEN as cookie correctly. But when I am sending the the POST request, the X-XSRF-TOKEN is not attaching itself with the header. And I am getting a 'token mismatch' error.
The front-end is on my localhost:8080 while the API is live on a url. I do not have direct access to the Laravel project but only the API.
Following is my axios configuration
import Vue from 'vue';
import axios from 'axios';
Vue.prototype.$axios = axios;
const apiBaseUrl = "https://someweburl.com";
const api = axios.create({ baseURL: apiBaseUrl });
api.defaults.withCredentials = true;
Vue.prototype.$api = api;
Vue.prototype.$apiBaseURL = apiBaseUrl;
export { axios, api, apiBaseUrl }
Following is the request format that I am trying to achieve i.e A POST request after getting the CSRF
export const fetchAllEvents = async function (context, payload) {
this._vm.$api.get('/sanctum/csrf-cookie').then(response => {
this._vm.$api.post('/api/website/event/all').then(response => {
context.commit('setAllEvents', response.data.data);
}).catch(error => {
console.log(error);
})
}).catch(error => {
console.log(error);
})
}
When I check use Postman to make the POST request with X-XSRF-TOKEN added as header, i am getting the correct response. Which means the API is working correctly. But there's some issue with axios.
Any help will be appreciated.
Maybe that is because the Axios only sets the X-XSRF-TOKEN header when the front and backend have the exact origin. You mentioned you are trying with your frontend app at your localhost and the API is on the web at another URL.
See the axios GitHub repository for more information: https://github.com/axios/axios/blob/cd8989a987f994c79148bb0cacfca3379ca27414/lib/adapters/xhr.js#L179

sending refresh token in headers to Laravel backend

Using Postman I'm able to POST my refreshToken:
.
In my controller I can receive above token like so:
$request->header('refreshToken');
If I try to do the same using axios I receive the data in $request->refreshToken not in header
axios.post(
'mybackend/refreshToken',
{ 'refreshToken': myToken }
)
tried the 'headers' option in axios but no luck.
$request->header('refreshToken'); // I should receive the token here, from axios
I think you are sending the refreshToken in the body instead of the header.
It should be:
axios.post(
'mybackend/refreshToken',
{}, //body
{headers:{ 'refreshToken': myToken }} //header
)

Axios JWT doesn't send

I have a project divided in two layers. The back-end is developed in spring boot, secured by Sprint security and JWT, and the front-end is developed in Vue.js, using Axios library for communication between layers.
I receive the "Bearer token" authentication properly, and all the authentication process is done correctly. The issue appears when I try to send a request with a token header to access content but the token doesn't send, and the Spring boot returns null without the content.
Here is the code
getOffers: function () {
if (localStorage.getItem("userSession")) {
this.aux = JSON.parse(localStorage.getItem("userSession"));
this.token = this.aux.token;
this.tokenHeader = "Bearer "+this.token;
alert(this.tokenHeader)
};
console.log(`Bearer ${this.token}`)
axios.
get('http://localhost:8080/api/v1/offer', {'Authorization' : `Bearer ${this.token}`})
.then(response => {
console.log(response);
this.offers = response.data
}).catch(e => console.log(e))
}
P.S: When I make a request in Postman, it works fine and returns the desired object. Here is a postman example:
postman
Correct way to pass header is :
axios.get(uri, { headers: { "header1": "value1", "header2": "value2" } })
In your case try this:
axios.get('http://localhost:8080/api/v1/offer', { headers:{Authorization : `Bearer ${this.token}`} })
Also, check in console if this gives correct Bearer token:
console.log(`Bearer ${this.token}`)
Register the Bearer Token as a common header with Axios so that all outgoing HTTP requests automatically have it attached.
window.axios = require('axios')
let bearer = window.localStorage['auth_token']
if (bearer) {`enter code here`
window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + bearer
}
And no need to send bearer token on every request.

I'm getting "blocked by CORS policy" when I try to call Instagram API using Axios [duplicate]

This question already has answers here:
Access-Control-Allow-Origin with instagram api
(1 answer)
CORS error, when i use instagram API with angularjs
(1 answer)
Closed 3 years ago.
I'm trying to fetch some images from my Instagram account in a Laravel application with Vue as front end. When I try to do it in a standalone Vue app, it works well, but when I do so with Laravel, I got a message saying "has been blocked by CORS policy: Request header field x-csrf-token is not allowed by Access-Control-Allow-Headers in preflight response."
I'm using Laravel 5.8 and the Vue and Axios that comes within in and I'm using Homestead as my localhost server.
I've tried a lot of tips that I found here and on Google but I had no success. Basically, I'm trying the very basic of Axios call
beforeMount() {
axios.get('https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]').then(response => console.log(response))
}
I already created a Cors middleware on Laravel and tried a lot of headers settings on Axios.
I'm basically trying to retrieve a list of my Instagram posts and bypass that cors / x-csrf error.
Laravel automatically applies the X-CSRF-TOKEN header to all axios requests. This is so you can communicate with your application without having to pass the CSRF token every time for POST, PUT, DELETE, etc.
resources/js/bootstrap.js (default settings)
/**
* Next we will register the CSRF Token as a common header with Axios so that
* all outgoing HTTP requests automatically have it attached. This is just
* a simple convenience so we don't have to attach every token manually.
*/
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
You should be able to remove the offending header by doing something like this:
beforeMount() {
// create a new instance so we don't delete the csrf token for other requests
let instance = axios.create();
// delete the x-csrf-token header
delete instance.defaults.headers.common['X-CSRF-TOKEN'];
// use the new instance to make your get request
instance.get('https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]')
.then(response => console.log(response))
}
Your AJAX request to the Instagram API endpoint has to be sent as a jsonp request which means the dataType of the request has to be jsonp.
This blob in axios repository contains an example of sending a request using jsonp which is mentioned below.
Install jsonp package, if you haven't already.
npm install jsonp --save
and then;
const jsonp = require('jsonp');
jsonp('http://www.example.com/foo', null, (err, data) => {
if (err) {
console.error(err.message);
} else {
console.log(data);
}
});
Below is an example of sending a request using jQuery method with jsonp dataType to the Instagram API endpoint.
$.ajax({
url: "https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]",
type: "GET",
crossDomain: true,
dataType: "jsonp",
success: function(response){
console.log(response);
}
});

How to authenticate Vue.js / Axios request of an API route in Laravel

I'm in Laravel 5.6. I have all my API routes built out and properly responding to requests from my REST client (Paw). I'm trying to build a simple front end to access those routes.
I'm trying to use Laravel's out-of-the-box features as much as possible, so I'm using Axios to call those routes from a blade template using Vue.js. It works if I disable auth middleware on the test route, but I get 401 errors on the console when auth middleware is enabled for the route.
The problem seems obvious enough... The auth:api guard on my /api routes wants to see an oauth token in the header, but when I log in with the web page it does session authentication. I assume there's a simple way to resolve this without having to spoof an oauth token request in the web frontend, right? Do I need to somehow pass the session token in my request with Axios? And, if so, do I also need to change the auth:api guard in my api routes file?
I solved it! I'm a bit embarrassed because the answer was actually in the Laravel docs, but I will say I tried this before posting the question here and it wasn't working. Perhaps something else was broken at the time.
Per the Laravel docs:
All you need to do is add the CreateFreshApiToken middleware to your
web middleware group in your app/Http/Kernel.php file:
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
This Passport middleware will attach a laravel_token cookie to your
outgoing responses. This cookie contains an encrypted JWT that
Passport will use to authenticate API requests from your JavaScript
application. Now, you may make requests to your application's API
without explicitly passing an access token...
You will probably want to use Larvel Passport or a JWT auth mechanism for obtain the Authorization token.
Seeing as how you're using axios, add a request interceptor to attach the access token to every request once you successfully authenticate. A simple example:
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// assume your access token is stored in local storage
// (it should really be somewhere more secure but I digress for simplicity)
let token = localStorage.getItem('access_token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
to use the auth:api first you need api_token inside your users table
Schema::table('users', function ($table) {
$table->string('api_token', 80)->after('password')
->unique()
->nullable()
->default(null);
});
also you can create a user for testing as follows
User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'api_token' => Str::random(60),
]);
in your layout use the following before #yield('content')
<script>
window.Laravel = <?php echo json_encode(['api_token' => (Auth::user())->api_token]); ?>
</script>
now you can use window.laravel.api_token inside your vue js to use it in headers
heres an example
var methods = new Vue({
el: '#tabs_lists',
data: {
config: {
headers: {
Authorization: 'Bearer ' + window.Laravel.api_token,
Accept: 'application/json'
}
},
data: []
},
methods: {
test: function (link) {
axios.get(link, this.config)
.then(response => (this.data = response.data)).catch(function (error) {
// handle error
console.log(error);
});
}
}
}
)

Resources