Laravel Auth modify for two kinds of users - php

I'm currently trying to modify the laravel Auth two be able to register two different kinds of users, a seller and a buyer. Both have the same form, except one field, that only the seller has, called companyName.
So what I did is putting a dropdown for registration instead of the normal register button, this is what I got there:
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
Registrieren
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li>
Als Käufer
Als Händler
</li>
</ul>
</div>
Then I made a route for this two kinds of registrations, like this:
Route::get('/register/{userType}', 'Auth\RegisterController#showRegistrationForm');
In the controller then I simply overwrote this showRegistrationForm function to pass the userType into my view, just like that:
public function showRegistrationForm($userType)
{
return view('auth.register', ['userType'=> $userType]);
}
And in my view, I got this:
#extends('master')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Registrieren
als <?php if ($userType == 'customer') echo "Käufer";if ($userType == 'seller') echo "Verkäufer";?></div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/register') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('sex') ? ' has-error' : '' }}">
<label for="sex" class="col-md-4 control-label">Anrede</label>
<div class="col-md-6">
<select class="form-control" id="sex">
<option value="male">Herr</option>
<option value="female">Frau</option>
</select>
</div>
#if ($errors->has('sex'))
<span class="help-block">
<strong>{{ $errors->first('sex') }}</strong>
</span>
#endif
</div>
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="firstName" class="col-md-4 control-label">Vorname</label>
<div class="col-md-6">
<input id="firstName" type="text" class="form-control" name="firstName"
value="{{ old('firstName') }}" required autofocus>
#if ($errors->has('firstName'))
<span class="help-block">
<strong>{{ $errors->first('firstName') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<label for="name" class="col-md-4 control-label">Nachname</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control" name="name"
value="{{ old('name') }}" required autofocus>
#if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
</span>
#endif
</div>
</div>
<?php if ($userType == 'seller'){ ?>
<div class="form-group{{ $errors->has('companyName') ? ' has-error' : '' }}">
<label for="companyName" class="col-md-4 control-label">Firmenname</label>
<div class="col-md-6">
<input id="companyName" type="text" class="form-control" name="companyName"
value="{{ old('companyName') }}" required autofocus>
#if ($errors->has('companyName'))
<span class="help-block">
<strong>{{ $errors->first('companyName') }}</strong>
</span>
#endif
</div>
</div>
<?php } ?>
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Addresse</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email"
value="{{ old('email') }}" required>
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Passwort</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
<label for="password-confirm" class="col-md-4 control-label">Passwort
wiederholen</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control"
name="password_confirmation" required>
#if ($errors->has('password_confirmation'))
<span class="help-block">
<strong>{{ $errors->first('password_confirmation') }}</strong>
</span>
#endif
</div>
</div>
<div style="display:none;" class="form-group{{ $errors->has('role') ? ' has-error' : '' }}">
<label for="role" class="col-md-4 control-label">Deine Rolle:</label>
<div class="col-md-6">
<input name="role" type="radio"
<?php if ($userType == 'customer') echo "checked";?> value="Käufer"> Käufer<br/>
<input name="role" type="radio"
<?php if ($userType == 'seller') echo "checked";?> value="Verkäufer"> Verkäufer
#if ($errors->has('role'))
<span class="help-block">
<strong>{{ $errors->first('role') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Registrieren
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
#endsection
So mostly basic, just few more fields then with the auth without modification and the companyName only showing up when accessed over the route /register/seller.
My RegisterController is of course also a bit modified, or especially the create function, it looks like this now:
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'firstName' => $data['firstName'],
'sex' => $data['sex'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role' => $data['role'],
'templateURL' => ""
]);
if($data['role'] == 'Verkäufer'){
Complaint::create([
'user_id' => $user->id,
'complaintCount' => 0
]);
}
switch($data['role']){
case 'Käufer':
$user->attachRole(2);
break;
case 'Verkäufer':
$user->attachRole(3);
$user->companyName = $data['companyName'];
$user->save();
break;
default:
$user->attachRole(2);
break;
}
return $user;
}
And now comes the problem: As you can see, in my "invidual" views, which is basically just one anyway, I still post to the url /register, which I thought should work, but it doesn't.... Any ideas why this is not working? I also tried to add individual routes, so something like that:
Route::post('/register/seller', 'Auth\RegisterController#create');
Route::post('/register/buyer', 'Auth\RegisterController#create');
but thats not working as well. In both cases, I just get the same window back, as if there was an error (so my data still entered (expect the password), but nothing is registered or entered in the db, but as well there are no errors showing up, neither in my view, nor in the console.
What's interesting as well is the network tab, it seems like it definetely sends the request to /register as it shows up there with status code 302, but as well there's the route /register/customer again, and I'm wondering why...What's also interesting is that I think that somehow it kinda works, as if I enter a password with less then 6 characters or 2 different passwords, I get an error, so somehow the form seems to be posted, but nothing is entered into the db....
Any ideas why this happens like this and whats the problem?

First of all, I'd like to suggest you a Polymorphic approach to saving the users. Right now, you have only 2 user types, what if you get a third user type (say retailer or wholesaler or blah blah)... and for each of them, you will require different fields which may or may not fit in for all user types...
So, go with this
class User
{
public function profile()
{
return $this->morphTo();
}
}
class Seller
{
public function user()
{
return $this->morphOne('App\User', 'profile');
}
}
class Buyer
{
public function user()
{
return $this->morphOne('App\User', 'profile');
}
}
Now, In your routes, add these
Route::get('login', 'LoginController#show')->name('login.show');
Route::post('login', 'LoginController#login')->name('login.post');
Route::get('register', 'RegisterController#show')->name('register.show');
Route::post('register', 'RegisterController#register')->name('register.post');
Route::get('logout', 'LoginController#logout')->name('login.logout');
Now, in your form add a dropdown/radio button for User Type selection (you can also make seprate and run different routes and make these fields hidden);
Say,
<select name="type">
<option value="1">Buyer</option>
<option value="2">Seller</option>
<select>
Your RegisterController#register can be as follows:
use App\Buyer;
use App\Seller;
use Validator;
class RegisterController extends Controller
{
public function show()
{
return view('auth.register');
}
public function register()
{
$inputs = request()->all();
$validator = $this->validator($inputs);
if($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$userInputs = array_only($inputs, ['name', 'email', 'password']);
$userInputs['password'] = Hash::make($userInputs['password']);
switch($inputs['type'])
{
case 1:
$sellerInputs = array_only($inputs, ['company_name']);
$seller = Seller::create();
$user = $seller->user()->create($userInputs);
case 2:
$buyer = Buyer::create();
$user = $buyer->user()->create($userInputs);
default:
$user = null;
break;
}
if(!$user) {
return redirect()->back(); //Show flash messsage etc... and redirect back to show an error
}
auth()->attempt(array_only($inputs, ['email', 'password']));
return redirect(route('some.route'));
}
protected validator($inputs)
{
$rules = [
'name' => 'required|min:1|max:50',
'email' => 'required|email|min:1|max:100',
'password' => 'required|min:6|max:25',
// Other rules
];
$messages = [
// Any special messages if required...
];
return Validator::make($inputs, $rules, $messages);
}
}
Use same kind of coding structure in LoginController... I am simply going to write the login behind logging in below
public function login()
{
$inputs = request()->all();
//Validator etc...
if(auth()->attempt(array_only($inputs, ['email', 'password']))) {
return redirect(route('some.route'));
} else {
return redirect()->back(); // Again... Show some error flash message
}
}
Note :- I have not tested the code but I am 99% sure this should work... I wrote all this down myself... Took a damn half an hour almost!
Hope everything is answered and you understood. Let me know in the comments below if you have any other query :)

Related

Laravel: Auth class after login is not working

I am using Laravel 5.7. I am stuck on one thing. After redirecting to next page I am not able to get the logged in user properties.
Auth::user()->id is returning me error of getting unknown property of undefined.
Auth::check() also returning me false. I have checked lot of questions on the stack and other platforms but none of them solve my problem.
Here is what I have tried so far:
View:
<form method="POST" action="">
#csrf
<div class="form-group {{ $errors->has('email') ? ' has-error' : '' }}">
<label>{{ __('lang.email_address') }}</label>
<input type="email" name="email" value="{{ old('email') }}" class="form-control" placeholder="{{ __('lang.email') }}">
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
<div class="form-group {{ $errors->has('password') ? ' has-error' : '' }}">
<label>{{ __('lang.password') }}</label>
<input type="password" name="password" class="form-control" placeholder="{{ __('lang.password') }}">
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
<div class="checkbox">
<label>
<input type="checkbox" name="remember_me" > {{ __('lang.remember_me') }}
</label>
</div>
<button type="submit" class="btn btn-warning btn-flat m-b-30 m-t-30 bg-login"> {{ __('lang.sign_in') }}</button>
<hr/>
<div class="register-link m-t-15 text-center">
<p>
{{ __('lang.forgot_your_password') }} {{ __('lang.click_to_reset') }}
</p>
</div>
</form>
controller:
public function postLogin(Request $request) {
$validator = validator($request->all(),[
'email'=>'required|email',
'password'=>'required'
]);
if($validator->fails()) {
return Redirect::back()->withInput()->withErrors($validator);
}
$user = User::where('role_id', User::ROLE_ADMIN)->where('email', $request->input('email'))->first();
if(!empty($user)){
$userdata = array(
'email'=>$request->input('email'),
'password'=>$request->input('password')
);
if(Auth::attempt($userdata)) {
return redirect('/admin')->with('success', trans('lang.login_success'));
} else {
return redirect('/admin/login')->withInput()->with('error', trans('lang.incorrect_email_password'));
}
}else{
return redirect('/admin/login')->with('error',trans('lang.you_are_not_allowed_action'));
}
}
I am redirecting to the admin page but it gives error of Auth class.
you did not define Auth class in your controller. define it like this:
<?php
namespace App\Http\Controllers;
use Auth;
It's possible you have problem with Auth class so try with one of these codes
\Auth::check()
\Auth::user()->id
or
auth()->check()
auth()->user()->id
You need to define use Auth on the top of the controller like this:
<?php
namespace App\Http\Controllers;
use Auth;
use Illuminate\Http\Request;

Laravel Redirect and Validation Error

I have created a Laravel form, but I have encountered a few problems. When the form submits with information that does not meet the requirements, I want the form to redirect and to display the validation errors on the form (under the input). Furthermore, when the form redirects, I want it to keep the previous (old) values. Please give me some guidance.
Problem:
When I input information that does not match the validation requirements, the form refreshes, but none of the validation errors show up and none of the old input stays. (I simply get a brand new form with none of the old inputs and no validation errors.)
HTML:
<form role="form" action="" method="post" class="registration-form">
<fieldset>
{{ csrf_field() }}
<div class="form-top">
<div class="form-top-left">
<h3>Insight Contributor Account Info</h3>
</div>
<div class="form-top-right">
</div>
</div>
<div class="form-bottom" style="height: 400px">
<!--Name-->
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<div class="col-md-8 col-md-offset-2">
<input id="name" type="text" class="form-control" name="name"
placeholder="Full Name (e.g. John Doe)" value="{{ old('name') }}">
<br>
#if ($errors->has('name'))
<span class="help-block">
<strong>{{ $errors->first('name') }}</strong>
<h3> name is required</h3>
</span>
#endif
</div>
</div>
<!--Email-->
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<div class="col-md-8 col-md-offset-2">
<input id="email" type="email" class="form-control" name="email"
placeholder="Primary Email Address (e.g.Jdoe#gmail.com)"
value="{{ old('email') }}"><br>
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<!--Password-->
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<!-- <label for="password" class="col-md-4 control-label">Password</label>-->
<div class="col-md-8 col-md-offset-2">
<input id="password" type="password" class="form-control"
placeholder="Password (at least 6 character)" name="password"><br>
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<!--PasswordConfirm-->
<div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
<div class="col-md-8 col-md-offset-2">
<input id="password-confirm" type="password" class="form-control"
placeholder="Confirm Password" name="password_confirmation"><br>
#if ($errors->has('password_confirmation'))
<span class="help-block">
<strong>{{ $errors->first('password_confirmation') }}</strong>
<h3> password mismatch</h3>
</span>
#endif
</div>
</div>
</div>
<div class="form-top" style="margin-top: 10px">
<div class="form-top-left">
<h3>Professional Information</h3>
</div>
</div>
<div class="form-bottom" style="height: 460px">
<!--Primary Industry(single value)-->
<div class="form-group{{ $errors->has('industry') ? ' has-error' : '' }}">
<div class="col-md-8 col-md-offset-2"><br>
<select class="form-control selectpicker" name="industry" id="industry">
<option selected disabled>Primary Industry</option>
<option>Art</option>
<option>Business</option>
<option>Law</option>
<option>Media</option>
<option>Medicine</option>
<option>Education</option>
<option>Technology</option>
<option> Science</option>
<option>Service</option>
<option>Other</option>
</select>
#if ($errors->has('industry'))
<span class="help-block">
<strong>{{ $errors->first('industry') }}</strong>
</span>
#endif
</div>
</div>
<!--Primary Job Function (single value)-->
<div class="form-group{{ $errors->has('job_function') ? ' has-error' : '' }}">
<div class="col-md-8 col-md-offset-2"><br>
<select class="form-control selectpicker" name="job_function"
id="job_function">
<option selected disabled>Primary Job Function</option>
#foreach($professions as $profession)
<option #if ($profession->id == old('job_function_id')) selected
#endif value="{{ $profession->id }}">{{ $profession->name }}</option>
#endforeach
</select>
#if ($errors->has('job_function'))
<span class="help-block">
<strong>{{ $errors->first('job_function') }}</strong>
</span>#endif
</div>
</div>
<!--Add relative experience (multi tag)-->
<div id="tags" class="form-group" style="margin-top: 30px">
<div class="col-md-8 col-md-offset-2"><br>
<select id="test" style="width: 100%;margin-left: 10%;" name="tags[]"
multiple>
<option value="root" disabled="disabled">Tags</option>
<option value="level11" parent="root" disabled="disabled">Subjects
</option>
<option value="level12" parent="root" disabled="disabled">Grades
</option>
<option value="level13" parent="root" disabled="disabled">Relationship
Management
</option>
<option value="level14" parent="root" disabled="disabled">Classroom
Management & Design
</option>
<option value="level15" parent="root" disabled="disabled">Curricula &
Resources
</option>
<option value="level16" parent="root" disabled="disabled">Professional
Growth & Career Management
</option>
<option value="level17" parent="root" disabled="disabled">More</option>
#foreach($tags as $tag)
#if($tag->category =='Subjects')
<option value='{{ $tag->id }}'
parent="level11"> {{$tag->name}}</option>
#endif
#if($tag->category =='Grades')
<option value='{{ $tag->id }}'
parent="level12"> {{$tag->name}}</option>
#endif
#if($tag->category =='Relationship Management')
<option value='{{ $tag->id }}'
parent="level13"> {{$tag->name}}</option>
#endif
#if($tag->category =='Classroom Management & Design')
<option value='{{ $tag->id }}'
parent="level14"> {{$tag->name}}</option>
#endif
#if($tag->category =='Curricula & Resources')
<option value='{{ $tag->id }}'
parent="level15"> {{$tag->name}}</option>
#endif
#if($tag->category =='Professional Growth & Career Management')
<option value='{{ $tag->id }}'
parent="level16"> {{$tag->name}}</option>
#endif
#if($tag->category =='More')
<option value='{{ $tag->id }}'
parent="level17"> {{$tag->name}}</option>
#endif
#endforeach
</select>
#if ($errors->has('tags'))
<span class="help-block">
<strong>{{ $errors->first('tags') }}</strong>
</span>
#endif
</div>
</div>
<!--Bio-->
<div class="form-group{{ $errors->has('bio') ? ' has-error' : '' }}">
<!-- <label for="bio" class="col-md-4 control-label">Short Bio</label> -->
<div class="col-md-8 col-md-offset-2"><br>
<textarea id="bio" class="form-control" placeholder="Brief profile bio"
name="bio">{{ old(nl2br('bio')) }}</textarea><br>
#if ($errors->has('bio'))
<span class="help-block">
<strong>{{ $errors->first('bio') }}</strong>
</span>
#endif
</div>
</div>
</div>
<div class="form-top" style="margin-top: 10px">
<div class="form-top-left">
<h3> Agreements </h3>
</div>
<div class="form-top-right">
</div>
</div>
<div class="form-bottom">
<!--Terms-->
<h2 class="section-heading">Cypress Community Principles</h2>
<p class="lead">
<br>
Teachers value each other for their expertise.<br><br>
Teachers believe in the power of collaboration and will work together to engage
in
open and honest dialogue, provide guidance and mentorship, and create content
that
supports growth and success for fellow teachers.<br><br>
Teachers will respect each other and be mindful of what they post. We encourage,
open and honest communication, a diversity of perspectives, and thoughtful
disagreement. Harassment, disrespect, and inappropriate content are not
tolerated.<br><br>
Teachers will actively engage in fostering a positive community of learning and
growth.<br><br>
Teachers are the most significant influence on a student’s academic achievement
and
will support fellow teachers as agents of change and innovators of
education.<br><br>
</p>
<form action="#"
onsubmit="
if(document.getElementById('agree').checked) {
return true;
} else
{ alert('Please indicate that you have read and agree to the Terms and Conditions and Privacy Policy');
return false;
}">
<input type="checkbox" name="checkbox" value=0 id="agree"/> I have read and
agree to
the Community Principle,
<a href="/terms" style="color: #5dc19f">Terms
and Conditions
</a> and
<a href="/privacypolicy" style="color: #5dc19f">Privacy
Policy</a><br><br>
</form>
<!--Signup botton-->
<button type="submit" id="submit" class="btn btn-default"
style="background-color: #a5d5a7">
<i class="fa fa-btn fa-user"></i> Sign me up!
</button>
<button type="button" class="btn btn-default" style="background-color: #a5d5a7">
<a class="btn btn-link" href="{{ url('/') }}" style="color: whitesmoke">
Cancel </a>
</button>
</div>
</fieldset>
</form>
PHP:
public function register(Request $request)
{
$tags = Tag::all();
$professions = Profession::all();
if ($request->isMethod('post')) {
$validator = $this->validateRegister($request->input());
if ($validator->fails()) {
return back()->withErrors($validator)->withInput(); //TODO
}
$user = Iuser::create([
'name' => $request['name'],
'email' => $request['email'],
'password' => bcrypt($request['password']),
'bio' => $request['bio'],
'industry' => $request['industry'],
'confirmation_code' => str_random(30),
'job_function' => $request['job_function'],
]);
$user ->tags()->sync($request['tags']);
#event(new NewUserWasRegistered($user));
if($user->save()){
return redirect('/insight/login')->with('success', 'Welcome to Cypress!');
}else{
return back()->with('error', 'Register failed!')->withInput();
}
}
$datas = array('tags' => $tags, 'professions'=>$professions);
#return $user;
return view('iauth.register')->with($datas);
}
protected function validateRegister(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
'password_confirmation' => 'required|min:6',
'bio' => 'required',
'industry' => 'required|string',
'job_function' => 'required|string',
], [
'required' => ':attribute is required',
'min' => ':attribute is too short',
'confirmed' => 'different passwords',
'unique' => 'This email exits',
'max' => ':attribute is too long'
]);
}
Allow me to take a different and a more structured approach to organizing your backend code.
First let's arrange that validator function into a class
https://laravel.com/docs/5.6/validation#creating-form-requests
write down: php artisan make:request RegisterUser
https://laravel.com/docs/5.6/validation
This will create something like this under App\Http\Requests:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterUser extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$content = [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6', //confirmed means it will receive password_confirmed aswell
'bio' => 'required',
'industry' => 'required|string',
'job_function' => 'required|string'
];
return $content;
}
}
On your Controller, you'd have:
use App\Http\Requests\RegisterUser;
.
.
.
public function register(RegisterUser $request)
{
//fetch the validated data to this $data variable, that is now an array
$data = $request->validated(); //Or all, whatever you'd like
//add this variable to the array
$data['confirmation_code'] = str_random(30);
//since all inputs have the same name as your table, you can just give it to him and he'll insert
//Whatever is in your $fillable array in Iuser, it will be filled and only that.
//If you send more data than needed, theres no worries as he will only insert what is in that array.
$user = Iuser::create(data);
//? dunno but sure
$user ->tags()->sync($request['tags']);
//Something about some event
#event(new NewUserWasRegistered($user));
return redirect('/insight/login')->with('success', 'Welcome to Cypress!');
}
Now, why I removed so much code:
Instead of having all in one place (you still have a few different operations in the controller), you have now separated it's logic structure. Validations of the requests made to the backend are in FormRequests and by the time it reaches the controller, they are validated and the Controller just needs to insert and outputs what is expected.
Q1. Should you have a try catch? If there is a chance the database is not local or something unexpected, yes.
Q2. Can I abstract even more code from the controller? Yes and you should, controller, in my opinion, should just call someone else (another class) to handle insert or update operations and return answers.
Q3. This is pretty and all but, how do I get my old values from the inputs? Whenever you're handling with FormRequests, Laravel returns a 422 status code, alongside an object called MessageBagError (not of much interest for now) but as long as you have old in your inputs (and the old('inputname') equals the name of the variable that is going to be received in this FormRequest - that is on your rules btw), blade will detect it and fill them. If, in on another situation, you want to redirect()->back()->withInput(); you can just set the $request or the array inside of withInput($data) and remember to keep {{ old ('value') }} and it SHOULD be automatically filled by Laravel (because {{ }} is explicit to laravel's blade and allows you to write php code in it if needed).
https://laravel.com/docs/5.6/requests#old-input
Q4. Why did I remove the HTTPPost validation? Because on your route folder, you can establish the routes and the httpverbs (e.g.
Route::get('home',function(){
return view('home');
})->name("home");
Route::post('register', "RegisterController#register");
//Meaning, anyone who attempts to access host/register by not using HTTPost will receive a 405 Status code (Method not allowed)
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Laravel admin login isn't working

Admin login don't work and don't give me any error.
I have this routes in web.php file:
Auth::routes();
Route::prefix('admin')->group(function () {
Route::get('/login','Auth\AdminLoginController#showLoginForm')->name('admin.login');
Route::post('/login','Auth\AdminLoginController#login')->name('admin.login.submit');
Route::get('/','AdminController#getIndex')->name('admin.dashboard');
Route::get('/logout','Auth\AdminLoginController#logout')->name('admin.logout');
Route::post('/password/email','Auth\AdminForgotPasswordController#sendResetLinkEmail')->name('admin.password.email');
Route::get('/password/reset','Auth\AdminForgotPasswordController#showLinkRequestForm')->name('admin.password.request');
Route::post('/password/reset','Auth\AdminResetPasswordController#reset');
Route::get('/password/reset/{token}','Auth\AdminResetPasswordController#showResetForm')->name('admin.password.reset');
});
And this functions in controller(I only put here which have the problems)
public function showLoginForm()
{
return view('auth.adminlogin');
}
public function login(Request $request)
{
//validate the form data
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
//attempt to log the user in
if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)){
//if successful, then redirect to their intended location
return redirect('/admin');
}
return redirect()->back()->withInput($request->only('email','remember'));
}
And in resources/views/auth/adminlogin.blade.php i have this code:
#extends('backend.public.includes.head')
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">ADMIN Login</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ route('admin.login.submit') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Login
</button>
<a class="btn btn-link" href="{{ route('admin.password.request') }}">
Forgot Your Password?
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
This was working days ago.. and now not, i'm looking all but don't find the error. In networking isn't showing anything and with a debug i don't see anything.
I try to reset password and when i reset it (i have a redirect in the function he redirect me good, only not working in normal login).
Errors aren't showed too
EDIT
Migrate file:
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->increments('id');
$table->string('name',50)->unique();
$table->string('email',200)->unique();
$table->string('password');
$table->boolean('public')->default(true);
$table->rememberToken();
$table->timestamps();
});
}
Seed file:
private $arrayAdmins = array(
array(
'name' => 'Lluis',
'email' => 'lluis.puig#correo.biz',
'password' => 'correo1',
'public' => 1
)
);
public function run()
{
self::seedAdmins();
}
public function seedAdmins()
{
DB::table('admins')->delete();
foreach ($this->arrayAdmins as $admin)
{
$a = new Admin;
$a->name = $admin['name'];
$a->email = $admin['email'];
$a->password = $admin['password'];
$a->public = $admin['public'];
$a->save();
}
}
The admin login isn't working if i created with the seed. (So the problem i guess is with the "user created" with the seed.
I try to create one with php artisan tinker and it works.
SOLVED
I check the seed. The problem was de password isn't encrypted!
This line :
$a->password = $admin['password'];
Must be like this:
$a->password = bcrypt($admin['password']);

Laravel 5 Add errors in an array using After Validation Hook

I'm trying to add a function in my app where users are allowed to change their account password. I have three fields and my view looks like this:
<form class="form" role="form" action="{{ url('users/updatePassword') }}" method="post">
{{ csrf_field() }}
<div class="form-group label-floating {{ $errors->has('oldpassword') ? 'has-error' : '' }}">
<label class="control-label" for="oldpassword">Old Password</label>
<input type="password" name="oldpassword" class="form-control">
#if ($errors->has('oldpassword'))
<span class="help-block">
<strong>{{ $errors->first('oldpassword') }}</strong>
</span>
#endif
</div>
<div class="form-group label-floating {{ $errors->has('newpassword') ? 'has-error' : '' }}">
<label class="control-label" for="newpassword">New Password</label>
<input type="password" name="newpassword" class="form-control">
#if ($errors->has('newpassword'))
<span class="help-block">
<strong>{{ $errors->first('newpassword') }}</strong>
</span>
#endif
</div>
<div class="form-group label-floating">
<label class="control-label" for="newpassword_confirmation">Confirm Password</label>
<input type="password" name="newpassword_confirmation" class="form-control">
</div>
<div class="form-group">
<button class="btn btn-raised btn-primary">Change</button>
</div>
</form>
Firstly, I want to check if all fields are completely filled up and for that I used Validator. And then check if the oldpassword is match from the database so I use if (Auth::attempt(array('password' => $request->oldpassword))) condition. I also found in the laravel 5.2 documentation the After Validation hook. I don't know what is wrong but it seems it don't validates the oldpassword field when I typed a wrong password.
My controller:
$validator = Validator::make($request->all(), [
'oldpassword' => 'required|max:255',
'newpassword' => 'required|min:6|max:255|confirmed',
]);
$validator->after(function($validator) use($request) {
if (Auth::attempt(array('password' => $request->oldpassword))) {
$validator->errors()->add('oldpassword', 'Old password dont match in our database.');
}
});
if ($validator->fails()) {
// Toastr
$title = "Oops!";
$message = "Please make sure to fill all required fields.";
$options = [
'progressBar' => false,
'positionClass' => 'toast-top-right',
'timeOut' => 6000,
];
Toastr::error($message, $title, $options);
return redirect()->back()
->withErrors($validator);
} else {
return 'success'; // for testing only
}
Any idea regarding this?
According to your code when you enter correct oldpassword you get the error. So change if(Auth::attempt..... to if(!Auth:attempt.... And also if you use Auth:attempt you have to logout user again(this method also requires unique field like username or email to identify the user). so it's better if you use following method
if (!\Hash::check($request->get('oldpassword'), \Auth::user()->password)) {
$validator->errors()->add('oldpassword', 'Old password dont match in our database.');
}

Laravel 5.2 - Auth: display custom error messages

How can I customize the error messages (such as "These credentials do not match our records.") that are displayed upon unsuccessful login/registration without having to touch the foundation files? I'm looking for a solution and hopefully an elegant one, at least not touching AuthenticatesAndRegistersUsers nor ThrottlesLogins :)
I'm using the AuthController and forms provided by Laravel after executing:
php artisan make:auth
Controller:
(it only has a constructor and two methods, the rest falls on the foundation, the methods are:)
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
Form:
<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}">
{!! csrf_field() !!}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label class="col-md-4 control-label">E-Mail</label>
<div class="col-md-6">
<input type="email" class="form-control" name="email" value="{{ old('email') }}" required>
#if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input type="password" class="form-control" name="password" required>
#if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary">
<i class="fa fa-btn fa-sign-in"></i>Login
</button>
<a class="btn btn-link" href="{{ url('/password/reset') }}">Forgot Your Password?</a>
</div>
</div>
Thank you!
You can override getFailedLoginMessage on the AuthController which comes from the AuthenticatesUsers trait
protected function getFailedLoginMessage()
{
return 'what you want here.';
}
Or not override it and set a lang value for auth.failed. The getFailedLoginMessage method will check for Lang::has('auth.failed') and use that if its available.
For the actual validation error messages you can override the postLogin and pass your own array of messages to validate, or if you wanted to change them globally you can adjust them in the appropriate lang file in resources/lang/{lang}/validation.php.
You don't want to override the getFailedLoginMessage() method in AuthController. The proper solution is to change the message in the designed location. If you look in the Resources > lang > en folder, you will see an auth.php file. In it, there is a "failed" attribute with a message you can customize. Change it there. The orignial getFailedLoginMessage() method in the Laravel auth files in vendor looks to that location for a custom message first, before settling on the default.

Categories