Laravel 5 built in User Authentication - php

I am trying to use Laravel 5 built in User Authentication.In this regard I would like to redirect user to a certain route/page/controller after successfully logged in. I am trying to change code of complied.php file. I am trying to change /home of below code, but it is not working.
trait AuthenticatesAndRegistersUsers
{
protected $auth;
protected $registrar;
public function getRegister()
{
return view('auth.register');
}
public function postRegister(Request $request)
{
$validator = $this->registrar->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException($request, $validator);
}
$this->auth->login($this->registrar->create($request->all()));
return redirect($this->redirectPath());
}
public function getLogin()
{
return view('auth.login');
}
public function postLogin(Request $request)
{
$this->validate($request, array('email' => 'required|email', 'password' => 'required'));
$credentials = $request->only('email', 'password');
if ($this->auth->attempt($credentials, $request->has('remember'))) {
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())->withInput($request->only('email', 'remember'))->withErrors(array('email' => $this->getFailedLoginMessage()));
}
protected function getFailedLoginMessage()
{
return 'These credentials do not match our records.';
}
public function getLogout()
{
$this->auth->logout();
return redirect('/home');
}
public function redirectPath()
{
if (property_exists($this, 'redirectPath'))
{
return $this->redirectPath;
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
public function loginPath()
{
return property_exists($this, 'loginPath') ? $this->loginPath : '/auth/login';
}
}
Thanks

You are not supposed to change anything in compiled.php
In RedirectIfAuthenticated middleware change,
return new RedirectResponse(url('/home'));
to
return new RedirectResponse(url('/'));
This basically redirects logged in user to desired path, once logged in user returns to website.
so,handle function lookes like below,
public function handle($request, Closure $next) {
if ($this->auth->check())
{
return new RedirectResponse(url('/'));
}
return $next($request);
}
after that add following in AuthController
public $redirectTo = '/';
public $redirectAfterLogout = '/';
so after successful login user wil be redirected to redirectTo and after logout user will be redirected to redirectAfterLogout.

Related

Laravel 7 - Redirecting different user roles to different view

The LoginController had this code before:
class LoginController extends Controller
{
public function showLoginForm(){
$roles = Role::all();
return view('auth.login', compact('roles'));
}
public function logout(Request $request){
Auth::logout();
$request->session()->flush();
return redirect('/');
}
public function login()
{
$credentials = $this->validate(request(),[
'email' => 'email|required|string',
'password' => 'required|string',
]);
if (Auth::attempt ($credentials)){//auth attemptdevuelve verdadero o falso en caso de que las credenciales correspondan o no
//Inician cambios RDAN
$user = Auth::user();
if($user->userRole() == 'admin') {
return redirect('main');
} else if($user->userRole() == 'externo') {
return redirect('es/user_form');
} else if($user->userRole() == 'profesor') {
return redirect('profesor_site');
} else if($user->userRole() == 'registrador') {
return redirect('select_lang');
} else {
return back()->withErrors(['email' => 'Incorrect user permissions'])
->withInput(request(['email']));
}
//Terminan cambios RDAN
}else{
return back()->withErrors(['email' => 'Incorrect user permissions'])
->withInput(request(['email'])); }
}
}
Then I changed it for:
class LoginController extends Controller
{
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/main';//RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
In the model User I have this for the roles:
public function roles()
{
return $this->belongsToMany(Role::class,'assigned_roles');
}
public function isAdmin(){
return $this->hasRoles(['admin']);
}
public function hasRoles(array $roles)
{
return $this->roles->contains(fn($role, $key) => in_array($role->name, $roles));
}
public function userRole(){
return $this->role->nombre_rol;
}
With the new changes on the LoginController I have no problem with the login, but obviously only redirect to the main view. So, I want to add the redirect view depend on the role, but when I add the public function login() that it had before it returns an error with the function userRole() on the model User. The error is
ErrorException
Trying to get property 'nombre_rol' of non-object
http://localhost/Servescol2.0.2/public/login
You don't need to override the login method. The login method currently will make a call to the authenticated method to see if it returns true truthy value and then return that as the response. You can override the authenticated method and have it return your redirect based on your conditions.
protected function authenticated(Request $request, $user)
{
if ($user->hasRoles(['admin'])) {
return redirect('main');
}
...
}
The error is caused by trying to access an attribute/relationship which doesn't exist, which returns null:
$this->role
The User belongs to many Role so there are multiple roles not a single one.
You could have a method to check for a single role:
public function hasRole($role)
{
return $this->roles->contains('name', $role);
}
Then you could adjust your conditionals:
if ($user->hasRole('admin')) {
Or use the hasRoles method instead:
if ($user->hasRoles(['admin']) {

How to redirect from google drive in laravel

I'm using google drive in my project for login with google.
It's working fine for me, but the problem is when user select email, in callback method user have to redirect to '/', but user will redirect to home, this is callback method :
public function callback(Request $request)
{
$googleUser = Socialite::driver('google')->stateless()->user();
$user = User::where('email', $googleUser->email)->first();
if (!$user) {
$user = User::create([
'name' => $googleUser->name,
'email' => $googleUser->email,
'password' => bcrypt(\Str::random(16))
]);
}
auth()->loginUsingId($user->id);
return $this->loggedIn($request, $user) ?: redirect(route('login'));
}
It's ok for next time user login with google, but for the first time redirect to home.
And in loggedIn function for the first time returned false because two_factor_type is off in default :
public function loggedIn(Request $request, $user)
{
if ($user->two_factor_type === 'on') {
auth()->logout();
$request->session()->flash('auth', [
'user_id' => $user->id,
'remember' => $request->has('remember')
]);
if ($user->two_factor_type === 'on') {
$code = ActiveCode::generateCode($user);
//TODO send sms
}
return redirect(route('login.twoFactor'));
}
return false;
}
Even in my LoginController or RegisterController i changed this :
protected $redirectTo = RouteServiceProvider::HOME;
To this :
protected $redirectTo = '/';
So why it will redirect to home ?
in app/Http/Controllers/Auth/LoginController check if the controller protected with middleware, e.g:
public function __construct()
{
$this->middleware('guest')->except('logout');
//meaning if there is user authenticated not guest,
//when he hit function other than logout()
//will be redirected to default landing, in code below
}
in app/Http/Middleware/RedirectIfAuthenticated will check if current auth()->user() is authenticated
change the default code to :
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home'); // here change the default redirected
}
return $next($request);
}
please check route file maybe in route file your '/' path will return home page view like below...
Route::get('/', function ()
{
return view('welcome');
});
so please try to change this with your need.
or please remove below line from your callback function
return $this->loggedIn($request, $user)

Laravel 7.2.2: AuthenticationException with AuthenticateSession middleware when using auth()->login() and redirect() and route('login')

I'm building a Laravel application from start with user login/registration function.
Below is some code of it:
// web.php
Route::middleware(['guest'])->group(function () {
Route::get('/register', 'UserController#register');
Route::post('/register', 'UserController#doRegister')->middleware('throttle:10,1');
Route::get('/login', 'UserController#login')->name('login');
Route::post('/login', 'UserController#doLogin')->middleware('throttle:15,1');
});
Route::get('/logout', 'UserController#logout');
// UserController.php
class UserController extends Controller
{
public function register()
{
return view('user.register');
}
public function doRegister(Request $request)
{
$this->validate($request, [
'name' => 'required',
'email' => 'required|email|unique:App\User',
'password' => 'required|confirmed'
]);
$userData = $request->only(['name', 'email']);
$userData['password'] = Hash::make($request->input('password'));
$user = User::create($userData);
auth()->login($user);
return redirect("/");
}
use ThrottlesLogins;
protected $maxAttempts=5;
protected $decayMinutes=1;
public function login()
{
return view('user.login');
}
public function doLogin(Request $request)
{
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$this->validate($request, [
'email' => 'required|email',
'password' => 'required'
]);
if (auth()->attempt($request->only(['email', 'password']), $request->boolean('remember_password')) == false) {
$this->incrementLoginAttempts($request);
return back()->withErrors([
'message' => __('auth.failed')
])->with('email', $request->input('email'));
}
$this->clearLoginAttempts($request);
return redirect()->to('/');
}
protected function username()
{
return 'email';
}
public function logout()
{
auth()->logout();
return redirect()->to('/');
}
}
The web page seem working.
When I enable middleware \Illuminate\Session\Middleware\AuthenticateSession::classin Kernel.php (for trial function "Invalidating Sessions On Other Devices" later), following error happen:
After creating new user success and redirect to home page with redirect("/"), Illuminate\Auth\AuthenticationException: Unauthenticated will happen and redirect again to login page (expected must go to home page with logged user).
Stacktrace:
E:\Web\movie-resumer\vendor\laravel\framework\src\Illuminate\Session\Middleware\AuthenticateSession.php:94
Stack trace:
#0 E:\Web\movie-resumer\vendor\laravel\framework\src\Illuminate\Session\Middleware\AuthenticateSession.php(55): Illuminate\Session\Middleware\AuthenticateSession->logout(Object(Illuminate\Http\Request))
This trace refer to following code in AuthenticateSession.php:
class AuthenticateSession
{
public function handle($request, Closure $next)
{
...
if ($request->session()->get('password_hash') !== $request->user()->getAuthPassword()) {
$this->logout($request);
}
...
}
}
I just try with other replacement as below in UserController#doRegister method:
Change auth()->login($user); to use auth()->attempt($request->only(['email', 'password'])); then Exception will not occur
Or: change return redirect("/"); to use return view('home'); then Exception will not occur (the URL http://localhost/register will show the home page with logged user)
Or: change/remove the route name 'login' (Route::get('/login', 'UserController#login')->name('login123');) then Exception will not occur.
Do my first implement has any mistake, so that it cannot working with AuthenticateSession middleware?

Laravel: How to register user through login?

I am using the standard method of login/registration of Auth Controllers. The goal is to register a new user when the user logs in if there is no such user, or just auth if there is. To my mind, it should be simply reassigning a couple of methods. For start, I changed
AuthenticatesUsers.php
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
$this->incrementLoginAttempts($request);
//return $this->sendFailedLoginResponse($request);
}
With commenting the last line it will not say that there is no such user, and I believe right there I should put register method, but I can't find the right way to include it. I suggest that I should use `RegisterUsers.php`
AuthenticatesUsers.php is the controller that does login logic. We are looking at the public function login
AuthenticatesUsers.php
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Validator;
use Illuminate\Auth\Events\Registered;
use Illuminate\Foundation\Auth\RegistersUsers;
trait AuthenticatesUsers
{
use RedirectsUsers, ThrottlesLogins, RegistersUsers;
public function showLoginForm()
{
return view('auth.login');
}
public function login(Request $request)
{
$this->validateLogin($request);
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
$this->incrementLoginAttempts($request);
//return $this->sendFailedLoginResponse($request);
$this->register($request);
}
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
protected function validator(array $data)
{
return Validator::make($data, [
//'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
//'password' => 'required|string|min:6|confirmed',
]);
}
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required|string',
'password' => 'required|string',
]);
}
protected function attemptLogin(Request $request)
{
return $this->guard()->attempt(
$this->credentials($request), $request->filled('remember')
);
}
protected function credentials(Request $request)
{
return $request->only($this->username(), 'password');
}
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}
protected function authenticated(Request $request, $user)
{
//
}
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
public function username()
{
return 'email';
}
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->invalidate();
return redirect('/');
}
protected function guard()
{
return Auth::guard();
}
}
simply override the register method from RegisterUsers.php into your LoginController.
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
Also add the validator protected function from RegisterController and edit according to your fields.
Also keep in mind to edit the User model fillable array and the relatively migration file of creating users table. Set Nullable() to fields you are not going to enter during Login.
Implement this method in your LoginController
protected function attemptLogin(Request $request)
{
// here you can check if user is present or just create.
return $this->guard()->attempt(
$this->credentials($request), $request->filled('remember')
);
}
All I had to do is to turn to User model, no need to specify any methods
here is how the function in AuthenticatesUsers.php should look like:
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
//return $this->sendFailedLoginResponse($request);
$user = User::where('email', '=', $_POST['email'])->first();
if ($user === null) {
return User::create([
'name' => $_POST['email'],
'email' => $_POST['email'],
'password' => Hash::make($_POST['password']),
]);
}
else
echo 'Wrong password';
}

Laravel multi auth 5.4

I am trying to implement multi auth in laravel 5.4 and have done it in this way,
i have already implemented guards and providers for the guards in auth.php,
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class FleetLoginController extends Controller {
public function __construct() {
$this->middleware('guest:company');
}
public function showLogInForm() {
return view('fleet.fleetLogin');
}
public function login(Request $request) {
$this->validate($request, [
'email' => 'required|email',
'password' => 'required'
]);
if (Auth::guard('company')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) {
$request->session()->regenerate();
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
} else {
return redirect()->back()->withInput($request->only('email', 'remember'));
}
}
public function logout(Request $request) {
$this->guard('company')->logout();
$request->session()->invalidate();
return redirect('/');
}
public function logcheck() {
if (Auth::check()) {
dd('yes logged in');
}
else
{
dd('No user logged in');
}
}
protected function authenticated(Request $request, $user) {
$this->logcheck();
}
protected function guard() {
return Auth::guard('company');
}
}
i have made the providers and guards, the problem is when i call the function logcheck()
it dumps "No user logged in". Can anyone help me? i need to get the id of the logged in user by
Auth::User()->id;
Seems like you need to use send name to guard
Auth::guard('company')->check() on logcheck()

Categories