register a public api route in laravel nova without authentication - laravel

I am developing a card for Laravel nova.
As part of this, I want an API route that can be posted, but I don't want to have to authenticate against it.
I have registered my route in the card's api.php
Route::post('/endpoint/{id}', function (Request $request, $id) {)
This works if I call it with an already authenticated session.
But if I try to call it from postman I get
HTTP 419 Sorry, your session has expired. Please refresh and try again.
I can see that the card service provider is registering the route as so
Route::middleware(['nova'])
->prefix('nova-vendor/NovaPusherCard')
->group(__DIR__.'/../routes/api.php');
So I guess that Nova is putting some authenticated in front of the route.
Is there a way I can register the route without adding authentication?

ok so I worked it out.
I just needed to update the middleware to api instead of nova.

Related

Laravel Jetstream/Sanctum API authentication

I have been working with Laravel since version 5.X up to version 8.X but always use it for backend API (never used blade template), and always pair it with VueJS on the front-end using JWT authentication (also never messed with any other authentication method).
Now with Laravel 9 and Vue 3, Im trying to use native Laravel Jetstream that uses SANCTUM and Vue+Inertia JS, and I'm quite lost with the authentication process. with JWT method, once the user succesfully login on the browser, all api request to Laravel will be authenticated using Authoraziation header. but this seems a different case with Sanctum.
After deploying and installing Jetstream and completed all the set-up. I created a user and loggedin with that user details. and I notice few things, there is a default API route
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
when I tried to directly access my.domain/api/user I notice it was redirected to GET /login
then redirected again to GET /dashboard
I then created a test api route using below
Route::get('test', function( Request $req) {
dd( [
'test' => $req->all(),
'user' => auth()->user(),
'request' => $req
] );
});
and I notice this request is not authenticated even when the cookies is present on the request as Im when I'm alraedy logged-in on the same browser, the auth()->user() is null.
I tried adding auth:sanctum middleware
Route::middleware('auth:sanctum')->get('test', function( Request $req) {
dd( [
'test' => $req->all(),
'user' => auth()->user(),
'request' => $req
] );
});
but having sanctum middle behave the same as the api/user where if i open api/test directly on the browser, it gets redirected to GET /login then redirected again to GET /dashboard and I'm quite lost at this point. I tried reading the docs and it says I have to do a separate authentication for this that would issue an API token and I was thinking I might better be going back with using JWT auth as it seems a lot easier to deal with.
So my question is; How can I authenticate an API end-point without having to redirect it to /login then /dashboard if the user is already logged in on my application using default sanctum authentication.
My goal is just to simply create /api/test that will be automatically authenticated if user already loggedin on the same browser and return the data I set on its return value and not doing any redirects.
Appreciate any help
I have got the same issue with laravel8
Jetstream and inertia vue3.
Am looking for the solution since 3 days posting messages on discord, searching on YouTube and more but nothing.
When i make an api call from your SPA to laravel, i got UNAUTHENTICATED response.
on postman you need put
headers
Accept = application/json
this tells your application know how works with Json
and go stop redirect to "Login"

Laravel returns unauthorized with second request

I'm trying to create SPA. I use Laravel API for backend and Nuxt.js for frontend. I want to authenticate users via Laravel Sanctum. I run backend on localhost:8000 and frontend on localhost:3000. SANCTUM_STATEFUL_DOMAINS is set to localhost:3000, SESSION_DOMAIN is set to localhost and SESSION_DRIVER is set to cookie.
I created login and logout in my app and everything works great until I make first request after logging in. I just wanted my app to return all users:
Route::middleware('auth:sanctum')->get('/users', function() { return User::all(); });
but it returns 401 unauthenticated. I don't know why is that happening. The route used for returning logged in user uses the same middleware:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
and works perfectly (Nuxt returns logged in user with every page change). I called users route with axios:
axios.get('http://localhost:8000/api/users')
What can cause this problem? This is very frustrating because I struggled a lot just to get the login and logout working.
I also thought about running API on api.domain.test and frontend on domain.test but is it possible to hook up a domain like that to Nuxt locally?
It returns unauthorized because the call to the endpoint doesn't have access token of the user.
The idea is that when you login auth:sanctum returns access token to the client so that it can use it to access the data in all of it's next calls.
To do that you need to use authentication module in nuxt check this
The problem you are going to face next is that SPA doesn't have middleware so you need to set your app as universal instead of spa to be able to use the middleware in the client side

Laravel authentication lifecycle

I'm trying to understand how an authentication request is handled by laravel in order to be able to write my own authentication method that allows me to check data from multiple tables before authenticating (basically there are some columns that I need to check to understand if a user is able to login).
I'm actually quietly confused about the relation between guards, middleware, provider and driver.
Can someone please explain me the lifecycle of a login request?
Thank you
EDIT: i'm working with laravel 5.7, standard Auth scaffolding that is available using make:auth
To make a custom authentication follow this steps
1.go to routes/web.php and make a get route to handle login view and post login route to handle login logic
Route::get('login','LoginController#show')
Route::post('login','LoginController#login')
2. Make a controller called LoginController
php artisan make:controller LoginController
4.inside LoginController make a function called login to handle login logic like this
public function login(){
$input = $this->validate(request(),['username'=>'required','password'=>'required']);
$model = CustomUsersModel::where('username',$input['username'])
->where('password',bcrypt($input['password']))->first();
if($model){
//user exist and valid login information
auth()->login($model);//login user via model
//now user loggedin
}
//handle wrong login information
}

Laravel 5.4: how to protect api routes

I have a react app that fetch datas from laravel api defined like so in routes/api.php:
// this is default route provided by laravel out of the box
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
// ItemController provides an index methods that list items with json
Route::resource('items', 'Api\ItemController', array('except' => array('create','edit')));
// this is to store new users
Route::resource('users', 'Api\UserController', array('only' => array('store')));
for example http://example.com/api/items returns the data as intended but it's really insecure since anyone could access it through postman.
How to make those routes only accessible inside the app?
As I'm new to it I don't understand if I need to set up api_token and how?
Do I need to setup Passport?
Is is related to auth:api middleware?
It may sounds really basic but any help or tutorial suggestions would be greatly appreciated
EDIT
End up with a classic session auth. Moved routes inside web.php. Pass csrf token in ajax request. Actually i didn't need a RESTful API. You only need token auth when your API is stateless.
As you are using Laravel 5.4 you can use Passport, but I haven't implemented yet, but i implemented lucadegasperi/oauth2-server-laravel for one of my laravel projects and it was developed in Laravel 5.1
Here is the link to github repository
lucadegasperi/oauth2-server-laravel
Here is the link to the documentation Exrensive Documentation
Just add the package to the composer json and run composer update,the package will get installed to your application , once installed add the providers array class and aliases array class as mentioned in the Laravel 5 installation part of the documentation,
you have to do a small tweak in order to work perfectly cut csrf from $middleware array and paste it into $routeMiddleware array and again run php artisan vendor:publish after publishing the migrations will be created and run the migration php artisan migrate
if you only want to secure api routes for each client like ios, android and web you can implement Client Credentials Grant, or if you need to every user with oauth the you can implement Authorization Server with the Password Grant or some other.,
Never use the client id or other credentials, generating access token in the form, but add it some where in helper and attach it in the request to the api,
Hope this answer helps you.
You could use JWT it's pretty easy to get it to work. You basically generate a token by requesting Username/Password and passing that token in every request that requires authentication, your URL would look like http://example.com/api/items?token=SOME-TOKEN. without a proper token, he doesn't have access do this endpoint.
As for
How to make those routes only accessible inside the app?
If you mean only your app can use these requests, you can't. Basically the API doesn't know who is sending these requests, he can only check if what you are giving is correct and proceed with it if everything is in order. I'd suggest you to have a look at this question

How to authenticate API requests in Laravel?

I am currently building some sort of posts based web application using Laravel 5(.4). I have decided to load asynchronously the comment section for each post(and refresh it periodically). After some research I have decided to write a small integrated REST API (using the api routes of Laravel) that should answer to the requests made through AJAX.
However, I am facing the problem if authenticating the incoming requests. Take for example a request to post some comment. How exactly would you recommend to do that?
If you are making AJAX requests from browser and you are signed in then you don't need to use Laravel Passport tokens.
You can define certain routes which will be using web,auth middleware on requests like webapi/comments/get like this.
Route::group(['middleware' => ['web','auth]], function () {
Route::get('webapi/comments/get', 'CommentsController#get');
}
And use Auth Facade as you do in web request i.e Auth::check(), Auth::user() etc. and return the data in JSON like this.
class CommentsController extends Controller
{
public function get(Request $request)
{
if($request->acceptsJson()){
$data = array();
// add data
return response()->json([
"data"=> $data,
"status" => true
]);
}else{
return abort(404);
}
}
}
You can also send Accept header in AJAX request as application/json and in controller check if request $request->acceptsJson() and make your decision to show content when url is loaded from browser address bar or requested as AJAX.
Laravel Passport token are useful where there is no session and cookies are managed.
hope this helps :)
"Passport includes an authentication guard that will validate access tokens on incoming requests. Once you have configured the api guard to use the passport driver, you only need to specify the auth:api middleware on any routes that require a valid access token" - from the Laraven Documentation.
Apparently I have to configure passport, and after that configure the auth:api middleware to use the passport driver. Correct me if I'm wrong, please :)

Resources