I'm working on Laravel task and struggling to add a login feature. Register and validation features seem work well, but can't login even if i put correct user_name and pass_word. also old helper function is not working as well.
i am a very beginner of Laravel and I know my code is messy and not coherent. But need to get this task done. appreciate if you help me solve this!
So here are files of my task. when i tried to login it always goes to this page.
<?php
use App\Http\Controllers\RegisterController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('users/list', 'App\Http\Controllers\UserController#getUser');
Route::get('register', [RegisterController::class, 'create'])->middleware('guest');
Route::post('register', [UserController::class, 'register'])->middleware('guest');
Route::get('login', [UserController::class, 'loginView']);
Route::post('login', [UserController::class, 'login']);
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UserLoginRequest;
use App\Http\Requests\UserRegisterRequest;
use App\Models\User;
use App\Services\UserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
private $userService;
public function __construct(
UserService $userService
) {
$this->userService = $userService;
}
public function getUser() {
$users = User::all();
return view('users/list')
->with('users', $users);
}
public function register(UserRegisterRequest $request)
{
$this->userService->registerUser($request->user_name, $request->pass_word);
return redirect('users/list');
}
public function loginView()
{
return view('users/loginView');
}
public function login(Request $request)
{
$validatedData = $request->validate([
'user_name' => ['required'],
'pass_word' => ['required'],
]);
if (Auth::attempt($validatedData)) {
$request->session()->regenerate();
return redirect('users/list');
}
return back()->withErrors([
'user_name' => 'wrong username'
]);
}
}
<main>
<h1>Login!</h1>
<form action="login" method="POST">
#csrf
<div>
<label for="user_name">
User_name
<input type="text" name="user_name" id="user_name" value="{{ old('user_name') }}" >
</label>
#error('user_name')
<div class="error">{{ $message }}</div>
#enderror
</div>
<div>
<label for="pass_word">
Password
<input type="password" name="pass_word" id="pass_word" value="{{ old('pass_word') }}">
</label>
#error('pass_word')
<div class="error">{{ $message }}</div>
#enderror
</div>
<div>
<button type="submit">
Submit
</button>
</div>
</form>
</main>
<?php
namespace App\Services;
use Illuminate\Database\Eloquent\Collection;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserService
{
/**
*
*
* #param string $name
* #param string $email
* #param string $pass_word
* #return void
*/
public function registerUser($user_name, $pass_word) : void
{
$user = new User();
$user->user_name = $user_name;
$user->pass_word = Hash::make($pass_word);
$user->save();
}
}
enter image description here
First, if you want to redirect using back() helper to another controller method, you should put ->withInput or ->onlyInput('user_name').
back()->withErrors([
'user_name' => 'wrong username'
])->onlyInput('user_name');
or
back()
->withErrors([
'user_name' => 'wrong username'
])->withInput();
You may dump the errors on the view because probably it comes from the password error may be?
Related
I am trying to integrate recaptcha to a query form, where the user enters only one piece of data and it returns the result that is extracted from the database.
I'm using
https://github.com/anhskohbo/no-captcha
But a validation is needed from the controller
Something like this appears in your documentation
$validate = Validator::make(Input::all(), [
'g-recaptcha-response' => 'required|captcha'
]);
Adjusted it for Laravel 8
But since I have my form in a GET method, I cannot use the validations, so I use your wisdom to be able to achieve the integration with recaptcha
This is my ListadoRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ListadoRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'texto' => 'required',
'g-recaptcha-response' => 'required|captcha',
];
}
}
This is my controller:
namespace App\Http\Controllers;
use App\Models\Listado;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Requests\ListadoRequest;
class ListadoController extends Controller
{
public function index(ListadoRequest $request){
$validated = $request->validated();
//other code
}
This is my web.php
Route::get('/busqueda', [ListadoController::class, 'index'])->name('busqueda');
When I try to enter the form it does not enter and stays on the main page
If I remove the validation line and change ListadoRequest to Request I access my form but obviously the captcha is a lie because it is not required
Update
My view
<form action="{{route('busqueda')}}" method="get">
<input type = "text" class="form-control" name="texto" value="{{$texto}}" >
<br>
{!! NoCaptcha::display() !!}
<input type=submit class="btn btn-primary" value= "Buscar">
</form>
Help pls :(
Hello guys is there any ways to redirect the logout function of Fortify?
<div class="nav-link" id="nav-bar-logoutbutton">
<form method="POST" action="{{ route('logout') }}">
#csrf
<button class="btn btn-secondary btn-sm" type="submit">Logout</button>
</form>
</div>
this is my blade logout
You can do the following:
Create a new LogoutResponse class and implement your redirect logic into the toResponse method:
"app/Http/Responses/LogoutResponse.php"
<?php
namespace App\Http\Responses;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Laravel\Fortify\Contracts\LogoutResponse as LogoutResponseContract;
use Symfony\Component\HttpFoundation\Response;
class LogoutResponse implements LogoutResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* #param Request $request
*
* #return Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 204)
: redirect('www.example.com');
}
}
Now you can bind the new response into the service container in the boot method of your FortifyServiceProvider:
"app/Providers/FortifyServiceProvider.php"
public function boot()
{
$this->app->singleton(
\Laravel\Fortify\Contracts\LogoutResponse::class,
\App\Http\Responses\LogoutResponse::class
);
}
In your config/fortify.php, add:
'redirects' => [
'logout' => 'login',
],
Just create a new post request in your routes/web.php
Route::post('logout', [ClientController::class, 'logout'])->name('logout');
Now in your controller, create a function to handle the request, make sure to include the Auth class at the top.
use Auth;
/* Process the logout request */
public function logout(Request $request) {
Auth::logout();
return redirect('/login')->with(['msg_body' => 'You signed out!']);
}
Instead of /login, you can redirect to anywhere.
I have this scenario in my app where I have to send user's password and username to their email right away after their account created by admin. Here is what I've done so far :
Controller :
public function store(Request $request) {
$data = $request->all();
$validasi = Validator::make($data, [
'name' => 'required|max:255',
'username' => 'required|max:255|unique:users',
'email' => 'required|email|max:150|unique:users',
'password' => 'required|confirmed|min:6',
'level' => 'required|in:admin,author',
]);
if ($validasi->fails()) {
return redirect('user/create')->withInput()->withErrors($validasi);
}
$data['password'] = bcrypt($data['password']);
$email = $data['email'];
Mail::to($email)->send(new UserAdded());
User::create($data);
return redirect('user');
}
The email will send successfully but I want to pass $data['username'] and $data['password'] to email view as well.
email view :
<div class="row">
<div class="col-sm-12 col-xs-12">
<h2><span>Welcome new User!</span></h2>
<p>Your username </p>
<p>Your password</p>
</div>
Mailable function :
class UserAdded extends Mailable
{
use Queueable, SerializesModels;
public function __construct()
{
}
public function build()
{
return $this->view('email/newuser');
}
}
How to do it ? where will I define the $user data ? thanks for the help!
First of all, you need a class that builds the view. There you can define properties which you'll pass to the class. They'll be accessable in the view then.
<?php
namespace App\Mail;
use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class UserAdded extends Mailable
{
use Queueable, SerializesModels;
public $username;
public $password;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($username, $password)
{
$this->username = $username;
$this->password = $password;
}
public function build()
{
return $this->view('reference.your.view.path.here'); //CHANGE
}
}
You can now access the variables in your view.
<div class="row">
<div class="col-sm-12 col-xs-12">
<h2><span>Welcome new User!</span></h2>
<p>Your username: {{$username}} </p>
<p>Your password: {{$password}} </p>
</div>
Calling your view can be realized like this:
Mail::to($email)->send(new UserAdded($data['username'],$password));
I am customizing laravel 5's built in login so that it would redirect to three different paths according to the type column which i added to the users table, i tried altering the handle function of RedirectIfAuthenticated middleware. but it seems that it always finds the home URI.
here is my edited middleware
public function handle($request, Closure $next)
{
if ($this->auth->check() && $this->auth->user()->type == 'patient') {
// return redirect('/home');
return 'PATIENT VIEW';
} elseif ($this->auth->check() && $this->auth->user()->type == 'doctor') {
return 'DOCTOR VIEW';
} elseif ($this->auth->check() && $this->auth->user()->type == 'nurse') {
return 'NURSE VIEW';
}
return $next($request);
}
Im new to laravel 5 and i would really appreciate any help and explanations
RedirectIfAuthenticated is being misused here. That middleware is for when an authenticated user tries to access a page that should only be accessed by guests. For example, if I am a user and I try to view the login or registration forms, it doesn't let me.
I would not mess with the authentication itself... some of it is easily customizable but what you're trying to do is not. I would just let Laravel authenticate them first and then handle what to do after.
/home is the default route users are taken to when they login. Move your if checks to that route controller method. Better yet... if you set things up right you don't need any checks at all.
class HomeController {
public function index()
{
$user = \Auth::user();
return view($user->type . '.dashboard');
}
}
Now you just need views named patient/dashboard.blade.php, doctor/dashboard.blade.php, etc. If you have more complex logic then you might want an actual redirect
return redirect('home/' . $user->type);
Define routes for each of those types
Route::get('home/patient', 'PatientController#dashboard');
Route::get('home/doctor', 'DoctorController#dashboard');
Route::get('home/nurse', 'NurseController#dashboard');
And then do whatever you need to in those controller methods.
Check out the docs in Authentication section
Basically what you need is:
Create the auth routes at app/Http/routes.php:
// Authentication routes...
Route::get('auth/login', 'Auth\AuthController#getLogin');
Route::post('auth/login', 'Auth\AuthController#postLogin');
Create the login form view:
<!-- resources/views/auth/login.blade.php -->
<form method="POST" action="/auth/login">
{!! csrf_field() !!}
<div>
Email
<input type="email" name="email" value="{{ old('email') }}">
</div>
<div>
Password
<input type="password" name="password" id="password">
</div>
<div>
<input type="checkbox" name="remember"> Remember Me
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
Manually Authenticate users app/Http/Controllers/Auth/AuthController.php:
<?php
namespace App\Http\Controllers;
use Auth;
use Illuminate\Routing\Controller;
class AuthController extends Controller
{
/**
* Handle an authentication attempt.
*
* #return Response
*/
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password])) {
if (Auth::user()->type == 'patient'){
return redirect()->intended('patientDashboard');
}
if (Auth::user()->type == 'doctor'){
return redirect()->intended('doctorDashboard');
}
}
}
}
Or if you want to keep the logic under RedirectIfAuthenticated middleware you could just fix your code:
public function handle($request, Closure $next)
{
if ($this->auth->check())
{
//we have a logged user check if it's patient
if($this->auth->user()->type == 'patient'){
return new RedirectResponse(url('/patient'));
}else if($this->auth->user()->type == 'doctor'){
return new RedirectResponse(url('/doctor'));
}
}
return $next($request);
}
Also you should check out this Entrust package.
I'm having trouble logging in. Even when there are no validation errors to be found, it goes to the else statement block in my postIndex method and brings me back to the login page. Any idea on what the problem is and what do i need to change to fix it?
routes.php
<?php
Route::get('/', 'HomeController#getGuestIndex');
Route::controller('login', 'LoginController');
?>
HomeController.php
<?php
class HomeController extends BaseController {
public function getGuestIndex()
{
return View::make('guests.index');
}
public function getAdminIndex()
{
return View::make('admin.index');
}
}
?>
LoginController.php
<?php
class LoginController extends BaseController {
public function getIndex()
{
// Check if we are already logged in.
if (Auth::check()) {
return Redirect::action('HomeController#getAdminIndex')
->with('message', 'You are already logged in');
}
return View::make('guests.login')
->with('title', 'Login');
}
public function postIndex()
{
// Get all the inputs
$user = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
$validation = User::validate($user);
if ($validation->passes()) {
// Try to log the user in.
if (Auth::attempt($user)) {
return Redirect::action('HomeController#getAdminIndex')
->with('message', 'You have logged in successfully');
}
return Redirect::to('login')
->withErrors($validation)
->withInput(Input::except('password'));
} else {
// Something went wrong.
return Redirect::back()
->withErrors($validation)
->withInput(Input::except('password'));
}
}
}
?>
BaseModel.php
<?php
class BaseModel extends Eloquent {
public static function validate($inputs)
{
return Validator::make($inputs, static::$rules);
}
}
?>
User.php
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends BaseModel implements UserInterface, RemindableInterface {
protected $table = 'users';
protected $hidden = array('password');
protected static $rules = array(
'username' => 'required|alpha_dash|min:4',
'email' => 'required|email',
'password' => 'required|alpha_num|min:8|confirmed',
'password_confirmation' => 'required|alpha_num|min:8'
);
public function getAuthIdentifier()
{
return $this->getKey();
}
public function getAuthPassword()
{
return $this->password;
}
public function getReminderEmail()
{
return $this->email;
}
}
?>
login.blade.php
#extends('layouts.master')
#section('content')
<h2>Login into your account</h2>
{{ Form::open(array('url' => 'login')) }}
<p>
{{ Form::label('username', 'Username') }}
{{ Form::text('username', Input::old('username')) }}
</p>
<p>
{{ Form::label('password', 'Password') }}
{{ Form::password('password') }}
</p>
<p>
{{ Form::submit('Login') }}
</p>
{{ Form::close() }}
<p>{{ $errors->first('username') }}</p>
<p>{{ $errors->first('password') }}</p>
#stop
Based on your question and example script the validation is failing.
The problem is likely with the model based validation implementation. You are validating login with registration rules.
One set of validation rules does not fit all situations.
If you add the following lines to your login.blade.php I think you will see additional errors:
<p>{{ $errors->first('email') }}</p>
<p>{{ $errors->first('password_confirmation') }}</p>
To fix it, you will need to either change the validation rules on your model, or change the validation implementation. These two excellent tutorials show a couple approaches:
https://tutsplus.com/lesson/validation-services/
https://tutsplus.com/lesson/validating-with-models-and-event-listeners/