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
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.
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;
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
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
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);
}
}
}