Laravel - Auth optional? - laravel

I have some endpoints in REST API that use Auth::id() as optional field. I mean action may be called both by guest and logged in user. Now, if I put route outside auth:api middleware it works but Auth::id() is returning null even if bearer header was sent. When I move routing to auth:api it works as intended for logged in user but obviously is not accessible for guests.
As a workaround I can create 2 similar endpoints (one for guests, one for logged users) but duplicating endpoints looks wrong :/

Related

Is it safe to delete the default route in api.php in Laravel 8?

I installed Laravel 8 and found the following route in routes/api.php.
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
I will create my own APIs which accept post and return json.
Should I remove the default sanctum route?
Is it safe to delete it? Or is it dangerous if I don't delete it?
I think it is dangerous if someone accesses /api/user. I don't know what it is.
I think it is dangerous if someone accesses /api/user. I don't know
what it is.
Yes it is good to remove this example route. On the other hand. Only authenticated User can see the userlist. If you are the only auth user in your application it not so much important if you forget to remove this route.
You can safely delete it. They just included it as an example or not to present you with an empty routes/api.php (not sure which).
Edit: Accessing /user will show the user associated with the bearer token. Sanctum's tokens aren't dependent on the /user route however.
Sacntum is cookie-based session authentication service. This is just an example route that will return the user data if he is logged-in. You can remove it safely without any issues.
It is completely safe to use as well as the user will only be able to access this route if he is already logged in and will only get his user information back not of all the users.

How to protect laravel api route from outside access but allow unrestricted access if request comes from frontend?

I'm building the backend with laravel and then using Vue as front-end. Data is accessed over api calls using axios. Now I have this relatively simple task but I can't seem to find the proper solution. I want one of the routes to be easily consumable by Vue compoenents without the need to log in, however I don't want that route to be publicly available for anyone to use.
Things I have tried:
Using passport to protect my routes and then use passport's CreateFreshApiToken middleware. Protection works fine, unauthorized users are not able to access the routes, however I don't get laravel_token in my cookies and therefore I can't get access to that route if I'm not logged in.
Use passport's client credentials grant access. Works fine and the way I want it to work but doesn't really make sense because if I hardcode the client_secret - anyone can access it and then use it to access protected routes. If I make a proxy-like solution, to call a controller method, which would issue a valid token and thus not exposing client_secret to front-end but then anyone could just call that route which issues the token and it would be pointless once again.
Apparently the answer is pretty simple and I was overcomplicating things. I don't know if this is the right/elegant way to do this but basically. If you don't need your api to be accessible from other applications (which I didn't) we can just put routes in web.php instead of api.php. This will ensure that web middleware is used and so it will use the basic csrf token validation, which is totally sufficient for protection against outside requests. You can also leave the route in api.php and just use web middleware on that route. The outcome is exactly what I needed - application is getting data over a route without any need to login AND that route is not available over postman or anything else.

Laravel 5 - Authentication with Login-Form (users) and API-Request (students)

I want to authenticate normal users (users-table) with login form and laravel auth.
Additionally I want to authenticate students (students-table) with API-request like:
mylaravelsite.com/?studentkey=XXXXXXXXXXXXXXXXXX&studentname=YYYYY
How can I do this? I think with a middleware?
How can I use the Auth class to check if the logged in person is user or student or guest?
I like to build applications in the following way:
A route having a single purpose, meaning, one route is for authenticating users and another route is for authenticating students
Validating data on the middleware before performing ANY operation
Now to your question:
If you really need, you can create different routes linked to the same authentication method, and create a middleware to each where you 'manipulate' run-type which class the Auth is going to be used
auth()->getProvider()->setModel(App\Student::class);
There are other ways to do this, depending on the way you wish to authenticate. If you want a more detailed explanation, give us a scenario to work on:
How the user authenticates vs how the student authenticates
What is going to differ from these 2 authentications and how its handled
Note: You're authenticating users with a HTTP request to a certain route, which is the same as your example link, except that you're giving an HTTPGET example and default is POST on authentication

Laravel route in multiple middelwares

I want to have the same route within the auth:api middleware, and also out of it.
Right now, if I include it in both, only the one out of the auth:api is taken into consideration, even if the user is logged in.
Is there a way that if the user is logged in it goes to auth:api and if not it goes out of any middleware?
The reason to do this is that if the user is logged in, I want to access user information, and for that it needs to go through the auth:api.
As long as you're including the token in the request, you will be able to get access to the current User.
Out-of-the-box, Laravel will set the default guard to be web. When you place routes under the auth middleware it will set the default guard to be whatever is passed to the middleware i.e. when you have auth:api it will set the default guard to be api for that request.
If you want to be able to access the User without it being under the auth:api middleware, you will simply need to be explicit with what guard should be used e.g.
auth('api')->user(); // or Auth::guard('api')->user();
The same applies for check():
auth('api')->check(); // or Auth::guard('api')->check();
or if you're using the Request object:
$request->user('api'); // or request()->user('api');
It 's not possible to have multiple same routes in your application and work independently. Laravel will match the first one that it find in your routes map.
Create one route and check for authentication in your controller.
if (Auth::check()) {
// The user is logged in...
}

Check if user is authenticated in laravel API route

So I know API routes are not supposed to rely on sessions authentication, but my idea was to create some API routes, that could be used if needs be by third-party with proper authentication, but that could also be used internally, ie called to get the data I need for my web pages.
I changed the LoginController so that every time a user logs in, a Personal Access token is generated and stored in the database. When logging out, this token is deleted.
So as not to expose the token to the client side, I would like to use a middleware, that would detect, on an API call, if the request comes from a user who is already authenticated. If that's the case, I would retrieve the Personal Access token that belongs to the user, attach it to the request, and pass it onto the API.
Browser -- Query site.com/api/myRoute --> Middleware adds user's token to request if Auth::check() -- Pass-on request --> Controller
I've created a dummy API route to see if I can detect whether a user is authenticated, but that doesn't seem to work... I guess because the 'auth' middleware is not included.. however, if I do include it, I get redirected to home on every request...
Route::get('/test', function() {
if(Auth::check()) {
dd('Hello logged-in');
} else {
dd('Hello not logged-in');
}
});
Any lead on how to achieve that much appreciated!

Resources