Vue cookie-based authentication in Laravel - laravel

From reading the Laravel docs, it appears that when using Sanctum Vue will just use the cookie-based authentication.
I was trying to move an existing app (with login done using Livewire) to Vue, but calls direct to my first api endpoint were redirecting to the login page.
So I created a clean installation of Larvel, installed Breeze (with Inertia), then Sanctum, published the config etc.
But when I login and then visit my test endpoint (which just returns 200 Ok), it redirects to the login page (which, because I am logged in, redirects to the Breeze dashboard).
Do I need to do anything manually for my endpoint, guarded by auth:sanctum, to pass authentication?
Update
I've set axios.defaults.withCredentials, and it's returning 401 Unauthorized. My app.js:
axios.defaults.withCredentials = true;
axios.get('/api/test')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});

First ensure that your application's CORS configuration is returning the Access-Control-Allow-Credentials header with a value of True. This may be accomplished by setting the supports_credentials option within your application's config/cors.php configuration file to true.
Then, if you are using axios, you should enable the withCredentials option on your axios instance:
axios.get('some api url', {withCredentials: true});
or globally:
axios.defaults.withCredentials = true;
If you are not using Axios to make HTTP requests from your frontend, you should perform the equivalent configuration on your own HTTP client.
Laravel Docs Reference.
If you are using Postman to test your api, here is a smart implementation of sanctum authentication requests. Basically you have to get the sanctum cookie first, and then send the cookie on XSRF-TOKEN header.

Related

blocked by CORS policy ionic to laravel

Hello I created an ionic project and I am posting values via ajax to laravel backend (laravell is hosted by MAMP on the background), Whenever I am trying it by postman it's working correctly with a code 200
But whenever I am trying it with my ionic project the code is here
function submitAxiosFormPost(e: React.FormEvent<HTMLInputElement>) {
//? e: React.FormEvent<HTMLInputElement>
// e.preventDefault();
axios.post('http://localhost:8888/api/register', {
name: username,
email: email,
password: password,
password_confirmation: passwordConfirm
})
.then(function (response) {
console.log(response);
window.localStorage.setItem('profile', JSON.stringify(response.data.user));
window.localStorage.setItem('token', JSON.stringify(response.data.access_token));
})
.catch(function (error) {
console.log(error);
// console.log("ERRRR:: ", error.response.data);
});
// name:Nairi7,
// email:hnairiareg7#gmail.com,
// password:Nairi7,
// password_confirmation:Nairi7,
console.log(`Username: ${username}\nEmail: ${email}\nPassword: ${password}\nPasswordConfirm: ${passwordConfirm}`);
}
it's bringing this error
Your Ionic code isn't the problem here. Rather, it's your backend.
The problem has to do with web browsers limiting access to servers with CORS enabled. Web browsers only allow requests to web servers with CORS enabled for security reasons, so malicious sites do not read your data. Below is a link from Mozilla that talks more about CORS:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
I'm not 100% sure what your backend code is, as I'm not familiar with Laravel, so I can't guide you on how to enable CORS for your backend. However, I'm attaching a link which has instructions on enabling CORS for whatever your backend may be (I think Laravel uses PHP, so you might want to check that):
https://enable-cors.org/server.html
Once you enable CORS on your backend, you should be good to go.
You should enable cors on your laravel backend. You may do it manually or use a package like this one https://github.com/fruitcake/laravel-cors

Why does one Route fail and the other work?

I am using Laravel to serve both my website and a stateless API. I use Passport with a token set in the cookie to Authenticate the API, this is handled by Passport.
I make calls to the API using axios within vue.js
I was getting an issue with an API call that was returning Unauthorized, all other requests were fine, by playing around I have arrived at the finding that
this.$axios.get('session/'+this.session+'/posts')
.then(response => { console.log(response.data); });
Route::get('/session/{code}/posts' , 'PostController#posts');
works; whereas
this.$axios.get('session/posts')
.then(response => { console.log(response.data); });
Route::get('/session/posts' , 'PostController#posts');
does not (returns 401 Unauthorized).
In the first example the $code value is simply an obfuscated ID and is not related to authentication, it is a string of characters. Also, session refers to an internal Application object and is not related to the php session at all.
This is in my Routes service provider:
Route::prefix('api')
->middleware('auth:api')
->namespace($this->namespace.'\API')
->group(base_path('routes/api.php'));
This sets a token in a cookie (laravel_token by default), and uses that to authenticate.
Other routes are successfully authenticating through this, when I add the variable to the route, it works!
Can anyone explain to me why the second version gives an Unauthorized response?
It appears to be the auth:api guard that makes this distinction, but I don't know where in the Laravel framework the actual check() code is.
Kindly check if your routes where a part of a prefix that has the auth:guard api activated. whereas you need to send api generated token to gain authorization.

Is there any way to generate Passport token on user login via web middleware?

I want to upload images via Vue2Dropzone package in my Laravel project but it keep throwing 401 Unauthorized error. The auth:api middleware works fine when the request is sent from axios. The package itself uses plain javascript to make a request.
I think I just need to pass the token via Vue2Dropzone's sending method but when I checked the database, the passport table was empty. I need to login via API route to generate its token but my project is a Multi Page Application and it doesn't do a user authentication via API at all. Instead, user is logged in via it's built in authentication on web routes.
Is there any way to generate passport token when a user logged in via web middleware without modifying its built in login controller? I need it to be like that so I can pass it to my Vue props like this in my blade file:
<my-component user-token="{{ Auth::user()->passportToken }}"></my-component>
Or maybe there is another solution for this problem? Please let me know.
Solved by adding X-CSRF-TOKEN on the header.
data() {
return {
dropzoneOptions: {
url: '/api/v1/productImageUploads',
thumbnailWidth: 150,
maxFilesize: 0.5,
thumbnailWidth: 200,
addRemoveLinks: true,
headers: {
"X-CSRF-TOKEN": document.head.querySelector("[name=csrf-token]").content
}
}
}
},

How can you make your own authenticated REST requests?

I'm using admin-on-rest behind a login screen. I'm writing a custom form component. When I do a fetch call to the same server AOR is using, I get a 401. How can I use the same auth data that AOR is using with its requests?
In your fetch call, include this second argument:
fetch(url, { credentials: 'include' })
otherwise the auth cookie isn't sent with the request.

Laravel 5.3 and VueJS 2 Authenticating

Im using Laravels default auth to lock down some paths in the routes/api.php file.
Route::get('/projects', 'ProjectController#index')->middleware('auth:api');
I log the user in via a PHP form (not via a http request via Vue).
This creates the session and when I submit a HTTP request via Vue I can see that the header includes the Cookie and X-CSRF-Token however I keep getting a 401 {"error":"Unauthenticated."}
In my config/auth I have api driver set as 'token' (have tried changing this to 'session' but that did work :/)
From my understanding and what I have read online I should be able to use the default Laravel auth functionality to accomplish API calls from Vue HTTP requests.
this.$http.get('/api/projects')
.then(response => {
this.projects = response.body;
})
.catch (err => {
console.log(err);
});
I've read about methods of authenticating by generating an JWT token and storing that in local storage when the user logs in. Is this the method I should use or should I be able to accomplish it with the default Laravel Auth middleware?
Hope my questions make sense, any help/advice would be appreciated.
The auth:api middleware doesn't use cookies, it uses api_token param, which can be passed via get or Bearer <token> header. Just use web middleware.
I suppose you need to access the same route in two ways - for API users and for browser users. So why don't you create two routes for one action?
// api group with /api prefix
Route::get('/projects', 'ProjectController#index')->middleware('auth:api');
// web group
Route::get('/projects', 'ProjectController#index')->middleware('web');

Resources