I am trying to change hashing in the laravel.
So I made custom SHA256 with salt in the RegisterController.
Register completed but how to change in the login?
protected function create(array $data)
{
$salt = Str::random(8);
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => '$SHA$' . $salt . '$' . hash('sha256', hash('sha256', $data['password']) . $salt),
]);
}
This is code of LoginController. $this->guard()->attempt($this->credentials($request)) this goes to something and hash then get token.
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Exceptions\VerifyEmailException;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Validation\ValidationException;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
/**
* Attempt to log the user into the application.
*
* #param \Illuminate\Http\Request $request
* #return bool
*/
protected function attemptLogin(Request $request)
{
$token = $this->guard()->attempt($this->credentials($request));
if (! $token) {
return false;
}
$user = $this->guard()->user();
if ($user instanceof MustVerifyEmail && ! $user->hasVerifiedEmail()) {
return false;
}
$this->guard()->setToken($token);
return true;
}
/**
* Send the response after the user was authenticated.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\JsonResponse
*/
protected function sendLoginResponse(Request $request)
{
$this->clearLoginAttempts($request);
$user = $this->guard()->user();
$token = (string) $this->guard()->getToken();
$expiration = $this->guard()->getPayload()->get('exp');
return response()->json([
'token' => $token,
'token_type' => 'bearer',
'expires_in' => $expiration - time(),
]);
}
/**
* Get the failed login response instance.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\JsonResponse
*
* #throws \Illuminate\Validation\ValidationException
*/
protected function sendFailedLoginResponse(Request $request)
{
$user = $this->guard()->user();
if ($user instanceof MustVerifyEmail && ! $user->hasVerifiedEmail()) {
throw VerifyEmailException::forUser($user);
}
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
/**
* Log the user out of the application.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function logout(Request $request)
{
$this->guard()->logout();
}
}
Here is (what I believe is) the correct way to add hashing functions:
Step 1: Create your hasher by implementing the Hasher contract:
namespace App;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
class Sha256Hasher implements HasherContract {
public function make($value, array $options = []) {
$salt = Str::random(8);
return '$SHA$' . $salt . '$' . hash('sha256', hash('sha256', $data['password']) . $salt),
}
public function info($value) {
// Implement something that works like https://www.php.net/manual/en/function.password-get-info.php
}
public function check($value, $hashedValue, array $options = [])) {
// Verify the hash here e.g.
return $this->make($value, $options) === $hashedValue;
// But more secure than this
}
public function needsRehash($hashedValue, array $options = []) {
return <a boolean whether the passwords needs rehashing>;
}
}
You can then extend the hashers with this hasher. In a service provider add:
Hash::extend('sha256', function () {
return new Sha256Hasher();
});
Then (finally) change your default hashing driver in your config/hashing.php:
'driver' => 'sha256',
This should switch your hashing to use your new driver and should not need any changes to views or models.
First, create this function where you can reuse it:
protected function hash($string){
return hash('sha256', $string . config('app.encryption_key'));
}
On user creation you have to call the function to hash the password:
protected function create(array $data){
return User::create([
'name' => $data['name'],
'password' => $this->hash($data['password'])
]);
}
On login, you would have to call hash function on password again:
protected function login(Request $request){
$user = User::where([
'email' => $request->request('email'),
'password' => $this->hash($request->input('password'))
])->first();
Auth::login($user);
$token = $user->createToken('MyApp')->accessToken;
return response()->json(compact('token', 'user'));
}
I think that is the best approach to consider.
Related
enter image description here
Login is failed, the credencials email and password, is correct, but laravel dont acces to dashboard
The password reset is worng to, the email is correct and i try chance of credentials on myphpadmin but dont entry.
this is my code
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*
* #return \Illuminate\View\View
*/
public function create()
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
/**
* Destroy an authenticated session.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
If you're mass assignment while attempting authentication make sure the form requested keys must same as Model's $fillable keys.
then try this:
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$credentials = $request->validated();
if (Auth::attempt($credentials)) {
return redirect()->intended(RouteServiceProvider::HOME);
}
return back()->with('message', 'The given credentials are not matched');
}
if you're working with multi guards, try this:
public function store(LoginRequest $request)
{
$credentials = $request->validated();
if (Auth::guard('web')->attempt($credentials)) {
return redirect()->intended(RouteServiceProvider::HOME);
}
return back()->with('message', 'The given credentials are not matched');
}
I have tested this example code from your and my implementation
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Hash;
use Session;
use App\Models\User;
class AuthenticatedSessionController extends Controller
{
/**
* Display the login view.
*
* #return \Illuminate\View\View
*/
public function create()
{
return view('auth.login');
}
/**
* Handle an incoming authentication request.
*
* #param \App\Http\Requests\Auth\LoginRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function store(LoginRequest $request)
{
$request->validate([
'email' => 'required',
'password' => 'required',
]);
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
return redirect()->intended('dashboard')
->withSuccess('Signed in');
}
return redirect("login")->withSuccess('Login details are not valid');
}
/**
* Destroy an authenticated session.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\RedirectResponse
*/
public function destroy(Request $request)
{
Session::flush();
Auth::logout();
return redirect('/');
}
/**
* Registration page.
*
*/
public function registration()
{
return view('auth.registration');
}
/**
* Store new user request handler
*
*/
public function storeUser(Request $request)
{
$request->validate([
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required|min:6',
]);
$data = $request->all();
$check = $this->create($data);
return redirect("dashboard")->withSuccess('have signed-in');
}
/**
* Store new user
*
*/
public function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password'])
]);
}
/**
* Dashboard for user
*
*/
public function dash()
{
if(Auth::check()){
return view('dashboard');
}
return redirect("login")->withSuccess('are not allowed to access');
}
}
Please check from your project and check flash messages if password was wrong check password hashing correctly
I'm trying to send the form information to database but when i submit the form this error appears:
ErrorException
Declaration of App\Http\Controllers\LivroController::authorize() should be compatible with App\Http\Controllers\Controller::authorize($ability, $arguments = Array)
CONTROLLER (LivroController)
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreUpdateLivro;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Livro;
class LivroController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
protected $request;
private $repository;
private $livro;
public function __construct(Livro $livro)
{
$this->livro = $livro;
}
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/* public function index()*/
// {
/* $title = 'listagem dos livros';
$livros = $this->livro->all();
return view ('livros/cadastro', compact('livros','title'));*/
// return view ('livros/cadastro');
// }
protected function validator(Request $request)
{
return Validator::make($request, [
'namel' => ['required', 'string', 'max:200'],
'autor' => ['required', 'string', 'email', 'max:200'],
'editora' => ['required', 'string', 'max:50'],
'categoria'=> ['required', 'string', 'min:50'],
'classificação'=> ['required', 'string', 'min:1','max:2'],
'descricao'=> ['required', 'string', 'min:200'],
'image'=> ['not required'],
]);
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function create(StoreUpdateLivro $request)
{
$user = Auth::user()->id;
$data = $request->all();
if($request->image->isValid()){
$image = $request->image->store('livros');
$data['image'] = $image;
}
Livro::create([
'users_id' => $user,
'namel' => $request['namel'],
'autor' => $request['autor'],
'editora' => $request['editora'],
'categoria'=> $request['categoria'],
'classificação'=>$request['classificação'] ,
'descricao'=>$request['descricao'],
'image'=>$request['image'],
]);
return view('livros/cadastro');
}
public function index()
{
$livro = DB::select('select * from livros');
return view('livros/mostrar_livros', [
'livro' => $livro,
]);
}
}
Remove authorize() method from LivroController and then,
go to StoreUpdateLivro file and set return true into authorize() method.
and also you don't need to validator method in your controller.
See more about the FormRequest in Laravel.
I think, you have a copy/paste problem
Delete LivroController:: authorize() method - you copied it from Form Request - and all will be work fine.
I need have two Listeners in same event, and when an user has been created in the system, Lavarel send my an email with the credentials and another to assign roles of users. It's possible have two listeners in same event? Why does the system show me this message?
When I create an user the system show me:
Too few arguments to function App\Events\User\Created::__construct(), 1 passed in C:\xampp\htdocs\bwm\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasEvents.php on line 205 and exactly 2 expected
This is my Event:
class UserCreated
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $user;
public $password;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($user,$password)
{
$this->user = $user;
$this->password = $password;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
This is my Listener Assign Roles:
class AssignRoles
{
private $request;
/**
* Create the event listener.
*
* #return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Handle the event.
*
* #param Created $event
* #return void
*/
public function handle(UserCreated $event)
{
$event->user;
switch($role = $this->request->role)
{
case $role == 'Asesor':
$event->user->assignRole('Asesor');
$asesoria = Asesoria::orderby('created_at', 'desc')->first();
$asesoria->user_id = $event->user->id;
$asesoria->published = true;
$asesoria->update();
break;
case $role == 'Comprador':
$event->user->assignRole('Comprador');
break;
default:
$event->user->assignRole('Writer');
}
}
}
This is my Listener Send Login Credentials:
class SendLoginCredentials
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param Created $event
* #return void
*/
public function handle(UserCreated $event)
{
Mail::to($event->user)->queue(
new LoginCredentials($event->user, $event->password)
);
}
}
In my function store of my UsersController I call to dispach:
UserCreated::dispatch($user, $password);
In my EventServiceProvider I have this:
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
'App\Events\User\UserCreated' => [
'App\Listeners\User\AssignRoles',
'App\Listeners\SendLoginCredentials',
],
];
You have two parameters in your constructor of UserCreated class and you are passing only one because you are dispatching it wrong way.
you can do it several ways:
Event::dispatch(new UserCreated($user, $password))
event(new UserCreated($user, $password))
Try these. Hope it works
I had a protected $dispachesEvents in User Model:
protected $dispatchesEvents = ['created' => 'App\Events\User\Created'];
That's why I got the error:
Too few arguments to function App\Events\User\Created::__construct(), 1 passed in C:\xampp\htdocs\bwm\vendor\laravel\framework\src\Illuminate\Database\Eloquent\Concerns\HasEvents.php on line 205 and exactly 2 expected
I deleted it, and put the call to the dispacher in my RegisterController.
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
//'password' => Hash::make($data['password']), //mutador en User model
'password' => $data['password'],
'surname1' => $data['surname1'],
'surname2' => $data['surname2'],
'comunidad_id' => $data['cbx_comunidad'],
'provincia_id' => $data['cbx_provincia'],
'municipio_id' => $data['cbx_municipio'],
]);
//dd($data['password']);
event(new Created($user,$data['password']));
return $user;
}
As I had a protected $dispatchesEvents in User Model,this it executes before that my call in the RegisterController.
I have a question about the built in user authentication functionality in laravel. I got the authentication part to work but it doesn't seem like a user is stored in the session.
Admin Controler Code:
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Validator, Input, Redirect;
use DB;
use Session;
class AdminController extends Controller
{
public function index(Request $request)
{
if(isset($_POST['submit'])){
$v = Validator::make($request->all(), [
'email' => 'required',
'password' => 'required',
],
[
'required' => 'This field is required.'
]);
if ($v->fails())
{
$messages = $v->messages();
return redirect()->back()->withErrors($v)->withInput();
}
else
{
$email = $request->input('email');
$pass = $request->input('password');
$whereData = [
['email',$email],
['password',md5($pass)]
];
$res = DB::table('tbl_admin_users')->where($whereData)->get();
if(!empty($res)){
$userid=$res[0]->id;
$fname=$res[0]->fname;
Session::put('userid', $userid);
Session::put('fname', $fname);
return Redirect('admin/dashboard-listing');
}
else
{
Session::flash('message', 'Email/Password is invalid!');
Session::flash('alert-class', 'alert-danger');
return Redirect('admin/login');
}
}
}
else{
return view('admin.admin-login');
}
}
public function logout()
{
Session::flush();
return Redirect('admin/login');
}
}
Middleware Authentication.php code:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Authenticate
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
return $next($request);
}
}
AuthController I have:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Where to redirect users after login / registration.
*
* #var string
*/
protected $redirectTo = '/';
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
}
Route after correct details and login page route:
Route::get('/admin/dashboard-listing',array('uses'=>'Admin\AdminDashboardController#index'));
After logout redirect route:
Route::get('/admin/login',array('uses'=>'Admin\AdminController#index'));
My question is that how can i use middleware in this code. because
after logout i can easily access the url .back button is also worrking
i want laravel user authentication through middleware ..
You need to manually login user with auth()->login():
$res = DB::table('tbl_admin_users')->where($whereData)->first();
if(!empty($res)) {
$userid = $res[0]->id;
$fname = $res[0]->fname;
Session::put('userid', $userid);
Session::put('fname', $fname);
auth()->login($res);
return Redirect('admin/dashboard-listing');
}
Alternatively, you can use the auth()->loginById($res->id) method.
I am created a Laravel 5.2 application; I need to limit failure login attempts.I am created a AuthController with following code; But not working logging attempt lock.
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use Auth;
use URL;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers;
protected $maxLoginAttempts=5;
protected $lockoutTime=300;
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
$this->loginPath = URL::route('login');
$this->redirectTo = URL::route('dashboard'); //url after login
$this->redirectAfterLogout = URL::route('home');
}
public function index()
{
return 'Login Page';
}
/**
* Handle a login request to the application.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function postLogin(Request $request)
{
$this->validate($request, [
'username' => 'required', 'password' => 'required',
]);
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if (Auth::attempt($credentials, $request->has('remember'))) {
return redirect()->intended($this->redirectPath());
}
if ($throttles) {
$this->incrementLoginAttempts($request);
}
return redirect($this->loginPath)
->withInput($request->only('username', 'remember'))
->withErrors([
'username' => $this->getFailedLoginMessage(),
]);
}
/**
* Get the needed authorization credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function getCredentials(Request $request)
{
return $request->only('username', 'password');
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
]);
}
}
After many failure login their is no error message displayed. I am added some line to display error in login.blade.php file
Assuming you have implemented the make:auth artisan command of laravel.
Inside of the loginController, change the properties:
protected $maxLoginAttempts=5; to protected $maxAttempts = 5;
and
protected $lockoutTime=300; to protected $decayMinutes = 5; //in minutes
you need to use ThrottlesLogins trait in your controller
....
use AuthenticatesAndRegistersUsers, ThrottlesLogins ;
...
take a look here https://github.com/GrahamCampbell/Laravel-Throttle
and here https://mattstauffer.co/blog/login-throttling-in-laravel-5.1
Second link is for L5.1, but I think shouldnt be different for L5.2
Hope it helps!
Have a nice day.
Just overriding the following 2 functions maxAttempts and decayMinutes will be good to go. This 2 functions belong to Illuminate\Foundation\Auth\ThrottlesLogins.php file. I have tested on Laravel 5.6 version and working fine.
public function maxAttempts()
{
//Lock on 4th Failed Login Attempt
return 3;
}
public function decayMinutes()
{
//Lock for 2 minutes
return 2;
}