Laravel Auth::login - laravel

On my application, i'm using the login from the Steam API.
When the user authenticate on steam, the app create a new user if he doesn't exists on the database, else he bring the user data.
In this process, even if i create or just select the user info, i get an array from the user, and i do the Auth::login($user, true); .
On this function it works, if i debug the Auth::user() he returns correctly.
On the view i can use the Auth::guest() too and it works.
But if i go to another page, that only logged users can join, Auth::guest() returns true, Auth::check() returns false, Auth::user() returns NULL... (on the controller).
How can i access the auth methods on the new controller?
Controller that fails with auth:
<?php
namespace App\Http\Controllers\Profile;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
use Auth;
class ProfileController extends Controller
{
public function __construct()
{
if(Auth::guest()) {
return redirect()->route('home');
}
}
public function index()
{
// die(var_dump(Auth::user()->id));
return view('pages/profile/profile');
}
}

Due to Laravel's architecture, Auth::user() will always return null if called directly from a controller's construct.
Instead you should reference the 'auth' middleware like the following:
class ProfileController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
...

Related

Same route return different view according to user role laravel 9

I have a column on my user table called role, and it can have 2 different values, "employer" and "employee".
What I want to achieve is, on /dashboard url;
if not logged in : return welcome view
if logged in as employer : return employer.dashboard view
if logged in as employee : return employee.dashboard view
Problem with this code is, I'm logging in with my employer user, and when I go to /dashboard, it sends me welcome view even though I'm logged in. It works fine with employee user. However when I switch places of two routes, Employer page works but Employee breaks. ( redirects to / ) It always uses last declared route instead of following the middleware.
My routing:
Route::prefix('admin')->middleware('role:employer')->group(function() {
Route::view('/dashboard', 'employer.dashboard')->name("dashboard");
});
Route::prefix('store')->middleware('role:employee')->group(function() {
Route::view('/dashboard', 'employee.dashboard')->name("dashboard");
});
Role middleware :
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class HasRole
{
public function handle(Request $request, Closure $next, string $role)
{
if (Auth::user()?->role != $role) {
return redirect()->route('welcome');
}
return $next($request);
}
}
I'd suggest moving the routing logic to a closure or controller, which would be much easier.
Route::get('/dashboard', function () {
if (auth()->user()->role === 'employer') {
return view('employer.dashboard');
} else {
return view('employee.dashboard');
}
})->name('dashboard');
And then for the middleware, you can just update the already available middleware RedirectIfAuthenticated to route the user to the home page if not logged in. Or just update RouteServiceProvider::HOME.

laravel manually authenticate user

I want to manually login a user in laravel 8. The problem is that authentication succeeds, but the authenticated user is not stored in the session(or the session is not updated). I use the method given in de docs.
My loginController has two methods: 1) showing the login form and 2) performing the login
<?php
namespace App\Http\Controllers;
use App\Http\Requests\LoginRequest;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function login(){
return view('auth/login');
}
public function validateLogin(LoginRequest $request){
if (Auth::attempt(['email'=>$request->email, 'password'=>$request->password])) {
$request->session()->regenerate();
return redirect()->to('/');
}
return back()->withErrors(['credentials' => 'Deze gegevens zijn niet bekend!']);
}
}
The controller redirects indeed to / , so the user is authenticated but after the redirect the autenticated users is unavailable, so somehow it is not stored in the session.
Does anyone know how to solve this?
I removed the id from the User model as I wanted to use the e-mailadress as the primary key. This violated the Authenticable trait so the session was not updated.
The usermodel needed the following function to replace the id with the email:
public function getKeyName(){
return 'email';
}
The same can be accomplished with:
protected $primaryKey = 'email';
public $incrementing = false;

Laravel override Login controller, login(). How do i retrieve logged in user data if i overwrite the login controller. I tried to get auth() data

I used laravel like 4 years ago. Had to work on a project on laravel and tried using my own authentication methods but mybad forgot there was already inbuilt better security authentication. I understand if my question seem to be basic.
As you can see the commented line "$userID = Auth::user()->userID;" the auth() is null therefore, userID cannot get its id from null. I am unable to get user session data in any other controllers as well.
Any kind of help or suggestions is appreciated.
P.S. i have used the default login and registration inbuilt function only required function like login is override code. I am using laravel v 4.2.3. I tried passing the userid as url parameter but then discarded it as inbuilt session data makes it more secure and easier
the login function of my controller looks like this
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = RouteServiceProvider::HOME;
public function __construct()
{
$this->middleware('guest')->except('logout');
}
protected function login(Request $request){
$user = new User(); //my model User
$result=$user->login($request); //result has the id of the user
if ($result) {
//$userID = Auth::user()->userID;
return redirect()->route('homepage');
}else{
return redirect()->route('login');
}
}
}
model for user login()
//Auth user then let them login
public function login($request){
$email = $request->input('email');
$password = $request->input('password');
$result=DB::table('users')
->where('email', $email)
->where('password', $password)
->get();
return $result;
}
My Routes.. its default route of "Auth::routes();"
Route::get('/homepage/{userID?}', function($userID = null){
return view('index', ['userID' => $userID]);
})->name('homepage');
Route::get('/evaluate/{userID?}', function ($userID = null) {
return view('evaluate', ['userID' => $userID]);
})->name('evaluate');
I installed a fresh new laravel and tried my code again and somehow it worked. Must have made some errors when trying to override the codes. Thank you

Laravel api routes not working, it's always redirecting

I am having an issue with laravel doing my backend Api.
What I am trying to do is return logged user data with Auth::user();
I wrote the controller, the route for the controller method in api.php but when I try to go to the /api/route I am redirected to Home.
I also tried to remove the __construct() method from the controller, When I do this and try to go to the /api/route, dd($user) is returning null.
My controller:
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Resources\TeacherResource;
use Illuminate\Support\Facades\Auth;
class teacherApiController extends Controller
{
public function __construct(){
$this->middleware('auth');
}
public function information(){
$user = Auth::user();
dd($user);
}
}
Api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::get('information', 'API\teacherApiController#information');
Anything I am doing wrong?
I am using the laravel authentication for register and login users.
I suppose you are not authenticated before calling this route that's why when the __construct was there it redirected you to the home, that's also why Auth::user() returns you null.
You are probably not authenticated before calling this route.
To manage the authentication you used laravel passport or even used JWT

Use multiple Auth guards for one Policy

I have implemented multiple Auth guards in a Laravel 5.4 project (one of for admins and the other for regular users). This has worked successfully so far and both admins and users are able to log in. I am now trying to implement a Policy class that works for both Auth guards. This is because I have certain models that I want all administrators to edit and only users who own the model to be able to edit. So I have defined a policy with this method.
App\Policies\ModelPolicy
public function update(User $user, Model $model)
{
if ($user->id === $model->user_id) {
return true;
}
if (Auth::guard('admin')->check()) {
return true;
}
return false;
}
Then in whatever controller method I have for my model:
App\Http\Controllers\ModelController
public function update(Model $model)
{
$this->authorize('update', $model);
// update model
}
This works perfectly if a regular user is logged in. However, when an admin user is logged in, it doesn't even reach the policy (I know this from error logging). I am guessing that the Policy class does something to automatically deny a request if the default guard in Auth::check() fails. However, since it is valid for my users to have one of several guards (not just the default), I need to bypass this behavior.
I know I could implement the admin logic in my controller method and only use the policy if I know I am dealing with a non-admin:
public function update(Model $model)
{
if (!Auth::guard('admin')->check()) {
$this->authorize('update', $model);
}
// update model
}
However, this can quickly spiral out of control if my admin condition is more complicated than simply being logged in. More importantly, all of this logic belongs in a Policy, not muddying up my controller.
How is it possible to use the same Policy class for multiple authentication guards?
I ended up overriding the authorize method on the base controller class to make the correct Guard the default Guard. Then, the $user argument passed into my policy will be an instance of whichever Auth guard the current user is logged in as.
app/Http/Controllers/Controller.php
use Auth
class Controller extends BaseController
{
use DispatchesJobs, ValidatesRequests;
use AuthorizesRequests {
authorize as protected baseAuthorize;
}
public function authorize($ability, $arguments = [])
{
if (Auth::guard('admin')->check()) {
Auth::shouldUse('admin');
}
$this->baseAuthorize($ability, $arguments);
}
}
Now that the Policy will be passed in either my User model or my Admin model, I need to make sure that I remove the type-hinting for the argument and check the type of the model that is passed in. I don't need to do any Auth::check() because I know that the $user that is passed in must be a logged in user of the type that I want.
App\Policies\ModelPolicy
use App\User;
public function update($user, Model $model)
{
if ($user instanceof User) {
return $user->id == $userId;
}
// Is an Admin
return true;
}
And now I have access to desired Auth guard to do whatever I want with it in my Policy.
You can override the "authorize" method in your common controller (/app/Http/Controllers/Controller.php):
class Controller extends BaseController
{
use AuthorizesResources, DispatchesJobs, ValidatesRequests;
use AuthorizesRequests {
authorize as protected laravelAuthorize;
}
public function authorize($ability, $arguments = [])
{
if (!Auth::guard('admin')->check()) {
$this->laravelAuthorize($ability, $arguments);
}
}
}

Resources