Get authenticated User in API controller in Laravel - laravel

I want to fetch the Authenticated User's data in API controller. How to do that?
Here is my API\CompanyController
public function selected_company(){
return Auth::user()->id;
}
The error I got through HTTP request...

To convey the comment in a comprehensible manner,
Either your controller should have a middleware, like
public function __construct()
{
$this->middleware('auth:api');
}
Or your route to the api should be passed through the middleware
Route::get('your-api-endpoint')->middleware('auth:api');

Related

How to get User()->id in Controllers (Laravel 8+)

I am trying to select tasks by user('id'), but I can't get it in a Controller, where I selecting data from DB.
I have tried many thing and some of them from stackoverflow, but it isn't working.
I tried:
1. $userId = Auth::check() ? Auth::id() : true;
2. Auth::user()->id;
3. public function getUserId(){
on Model} - and then get this value on Controllers
and some other things
I have the simplest code:
I installed registration: npm artisan ui --auth something like that
I installed vuejs (on Laravel)
I created api on Laravel, and some logic on vue
I didn't touch "app.blade.php" it's the same as it was.
I can get data, user: name, id and all what I want in file "app.blade.php" but I need those data in folder->file: App\Http\Controllers{{SomeController}}, but I don't know how.
Was someone in this situation?
How can I get user id in Controllers?
Thanks guys for earlier.
If you need user id, just use one of this :
auth()->id();
using Auth facade's
\Auth::id();
or, using Request instance
$request->user()->id
Follow this simple controller code, i showed 3 different way here :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class SomeController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function getUserId(Request $request)
{
$user = Auth::user(); // Retrieve the currently authenticated user...
$id = Auth::id(); // Retrieve the currently authenticated user's ID...
$user = $request->user(); // returns an instance of the authenticated user...
$id = $request->user()->id; // Retrieve the currently authenticated user's ID...
$user = auth()->user(); // Retrieve the currently authenticated user...
$id = auth()->id(); // Retrieve the currently authenticated user's ID...
}
}
Auth::user()->id;
This should work if you have Auth middleware on that controller method where you try to get it, please check do you added that middleware.
For checking you can use php arisan route:list command.
Is someone still searching an answer on this question. I have some explanation how can you do this.
Laravel has a Router which routes authorization process through that Controller which you want, so you should redirect that process on your Router and in Controller create constructor which allows you to take user id.
How can you do that?:
1. First of all you should find Controller and Route which responsible for authorization and registration users.
In my case it was:
a)App\Http\Controllers\HomeController
b)routes\web.php
2. Second, you should redirect your authorization Router to the Controller where you trying to get Auth::id();
In my case it was:
App\Http\Controllers\TasksController
so, in routes\web.php I did this:
//was
Route::get('/', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
//was
Auth::routes();
//was
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
//added
Auth::routes();
//added
Route::get('/home', [App\Http\Controllers\TasksController::class, 'index'])->name('home');
perhaps you should have index function on that controller
3. Third you should add constructor in your controller where you want to get user id, this constructor I took from HomeController, it already was there.
In my case it was:
public function __construct()
{
$this->middleware('auth');
}
code with function on my TasksController:
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
$userId = Auth::check() ? Auth::id() : true;
}
And now I can take user id.
PS: constructor I added on the top in class TasksController in Controller

JWT Auth doesn't work when __construct method in controller

In a Laravel Application, the JWT middleware doesn't work properly. I found out, that there is no auth check, when the controller has a __construct method.
class ProjectController extends Controller
{
public $company;
public $user;
public function __construct(Request $request)
{
$this->company = $request->user()->company;
$this->user = $request->user();
}
Api routes:
Route::group(['middleware' => 'jwt.auth'], function () {
Route::resource('/projects', 'Project\\ProjectController');
});
When i comment the __construct method, the system return a 401 as expected. But if the __construct method is not commented, the system returns a 500 because the company can not be found.
Why the __construct method doesn't work with jwt?
This has nothing to do with the jwt middleware, this is intended behavior from laravel, you can read more about it here.
Laravel collects all route specific middlewares first before running
the request through the pipeline, and while collecting the controller
middleware an instance of the controller is created, thus the
constructor is called, however at this point the request isn’t ready
yet.
You can find Taylor's reasoning behind it here:
It’s very bad to use session or auth in your constructor as no request
has happened yet and session and auth are INHERENTLY tied to an HTTP
request. You should receive this request in an actual controller
method which you can call multiple times with multiple different
requests. By forcing your controller to resolve session or auth
information in the constructor you are now forcing your entire
controller to ignore the actual incoming request which can cause
significant problems when testing, etc.
So the solution would be to get the user and company from the request in each controller method, but if you want to keep it in the constructor you could implement the following workaround:
class ProjectController extends Controller
{
public $company;
public $user;
public function __construct(Request $request)
{
$this->middleware(function ($request, $next) {
$this->company = $request->user()->company;
$this->user = $request->user();
return $next($request);
});
}
}

How to pass data to controller

I intend to pass ip received in User.php to my HomeController. How can I do this?
$ip = Request::ip();
Now I'm looking for the way to pass it to the controller. Then I plan to broadcast it.
Request IP in laravel using controller
You should use request facades. Following way:
<?php
use Illuminate\Http\Request;
public function index(Request $request)
{
dd($request->ip());
}
Is the IP received via the URL or is it tied to the User model?
If it's via URL then it'd be as simple as
Route::get('example.com/{ip}', 'Controller#someFunction');
then in the controller
public function someFunction($ip) {
... //$ip can be used in here
}
Or, if say there's an authenticated user with 'ip' as part of the model, you could access it in the controller by grabbing the authenticated user instance:
public function someFunction() {
$user = Auth::user();
//$user->ip;
}

Laravel 5.6 - How to get auth()->user() or $response->user() in api controller?

In api.php routes file below, there are public routes and private routes:
Route::group(['namespace' => 'API'], function() {
// Public routes (auth not required)
Route::group([], function() {
Route::get('/testauth1', 'TestController#testauth1');
// more public routes...
});
// Private routes (auth required)
Route::group(['middleware' => 'auth:api'], function() {
Route::get('/testauth2', 'TestController#testauth2');
// more private routes...
});
});
In the TestContoller these are the 2 methods called above:
class TestController extends Controller {
public function testauth1(\Request $request) {
// return auth()->user(); // does not return user
return $request->user(); // does not return user
}
public function testauth2() {
return auth()->user(); // returns user
}
}
Since the private route group has the auth:api middleware, we will ensure the user is authenticated by checking the token supplied in the Authorization Bearer header. Only if a valid token is present will the private routes be rendered to the authenticated user. This is why TestController#testauth2 returns the auth user correctly.
Now, anyone can access the public routes, with or without token. If there is no token supplied in the Authorization Bearer header, then we'll have no authenticated user, which makes sense. This is why TestController#testauth1 does not return an auth user. However, when a logged in user accesses /testauth1 public route, they provide their token in the Authorization Bearer header and therefore should be returned in TestController#testauth1 if not with auth()->user() at least with the $request->user() but we can't seem to access the user with their supplied token in that method.
Any idea how we can access the valid token user in all public route methods?
Pass the api guard as a parameter to fetch the authorized user without the middleware protecting the request.
$request->user('api');
// Or
auth('api')->user();
You are referencing Request from a root namespace: \Request. Instead, you should reference the Illuminate\Http\Request class.
You should remove the \ from your parameter and add the following line to your imports.
use Illuminate\Http\Request;
Alternatively, you could also reference the request class directly in your method:
class TestController extends Controller {
public function testauth1(Illuminate\Http\Request $request) {
return $request->user();
}
public function testauth2() {
return auth()->user(); // returns user
}
}
The auth() helper method or Auth Facade is globally available. It doesn't depend on the request that you are trying to access. The same goes for the request() and Request:: helpers I believe. In the case you are giving, you are referencing a wrong Request instance, hence giving a unexpected result.

Laravel rest API returns user object in the post request

I created an API for login and register with the passport package in Laravel. When I call the login url in Postman it returns key_token, refresh token and expired_date.
But I want also want to return the authorized user info in json (eg the username and pass and email).
I need this because the mobile phone team wants to integrate my web app.
Login controller method:
public function login(Request $request)
{
$this->validate($request,[
'username'=>'required',
'password'=>'required'
]);
$params = [
'grant_type'=>'password',
'client_id'=>$this->client->id,
'client_secret'=>$this->client->secret,
'username'=>request('username'),
'password'=>request('password'),
'scope'=>'*'
];
$request->request->add($params);
$proxy=Request::create('oauth/token','POST');
return Route::dispatch($proxy);
}
In my opinion, the best way to go is to create another URI that returns the authenticated user. This way, the client signs in and then performs a GET request to get the authenticated user. I like to simply set this URI to /user. Laravel side, you just have to create a route like this:
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:api');
By the way, this is how the GitHub API works.
Hope that helps.

Resources