How do I use md5 instead of bcrypt? - laravel

I need to use md5() instead of bcrypt() for storing passwords. But when I just do this:
protected function create(array $data)
{
return Account::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => md5($data['password']),
'datetoday' => Carbon::now(),
'lastip' => request()->ip(),
'confirmation' => bcrypt($data['password']),
]);
}
When I try to login it says the credentials are wrong.

Using md5() over bcrypt() is not recommended.
However you can manually authenticate user. Override login() method in LoginController
public function login(Request $request)
{
$user = User::where('username', $request->username)
->where('password',md5($request->password))
->first();
Auth::login($user);
return redirect('/');
}

You have to create new service provider.
app/providers/md5hashprovier.php
namespace App\Providers;
class MD5HashProvider extends \Illuminate\Hashing\HashServiceProvider
{
public function boot()
{
\App::bind('hash', function () {
return new \App\Classes\MD5Hasher;
});
}}
Next you have to create the MD5Hasher class. I'd suggest to locate it to
app/classes/MD5Hasher.php
class MD5Hasher extends BcryptHasher
{
public function check($value, $hashedValue, array $options = array())
{
$user = User::wherePassword(md5($value))->first();
return $user ? true : false
}
}
and register your new service provider to config/app.php in providers array
\App\Providers\MD5HashProvider::class,
This would enable auth with md5 password

Using MD5 is not a good idea anymore.
To get rid of the old MD5 records you can use the second trick here: http://john.cuppi.net/migrate-from-md5-to-bcrypt-password-hashes/

Related

Temporary identifier passed back by server does not match laravel socialite

I am facing an issue when trying to login and register a user using Twitter. Google is working except for Twitter. I cant seem to figure it out.
Temporary identifier passed back by server does not match that of stored temporary credentials. Potential man-in-the-middle.
<?php
namespace App\Http\Controllers;
use Exception;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
class TwitterController extends Controller
{
protected $redirectTo = '/home';
public function redirectToProvider($provider)
{
return Socialite::driver($provider)->redirect();
}
public function handleProviderCallback($provider)
{
$user = Socialite::driver($provider)->user();
$authUser = $this->findOrCreateUser($user, $provider);
Auth::login($authUser, true);
return redirect($this->redirectTo);
}
public function findOrCreateUser($user, $provider)
{
$authUser = User::where('provider_id', $user->id)->first();
if ($authUser) {
return $authUser;
}
return User::create([
'name' => $user->getName(),
'username' => $user->getName(),
'email' => $user->getEmail(),
'provider' => $provider,
'provider_id' => $user->getId()
]);
}
}

Laravel passport throwing error: 'Call to a member function createToken() on null'

So i'm trying to create an auth repository test using phpunit but i keep getting the error 'Call to a member function createToken() on null'. I think this is due to the RefreshDatabase trait but i'm installing passport on setup so i'm a bit lost. Any help is appreciated!
AuthRepository test
namespace Tests\Repository;
use App\Contracts\Auth;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class AuthRepositoryTest extends TestCase
{
use RefreshDatabase;
protected $authRepository;
protected function setUp(): void
{
parent::setUp();
$this->artisan('passport:install');
$this->authRepository = app()->make(Auth::class);
}
/**
* Test Successful Login
*
* #return void
*/
public function testSuccessfulLogin(): void
{
$request = new \Illuminate\Http\Request();
$request->setMethod('POST');
$request->replace(['name' => 'test', 'email' => 'test', 'password' => 'testing']);
$this->authRepository->register($request);
$request = new \Illuminate\Http\Request();
$request->setMethod('POST');
$request->replace(['email' => 'test', 'password' => 'testing']);
$this->authRepository->login($request);
}
}
Test Case
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
protected function setUp(): void
{
parent::setup();
}
}
AuthRepository
<?php
namespace App\Repositories;
use App\Contracts\Auth;
use Illuminate\Support\Facades\Auth as Authenticate;
use App\User;
class AuthRepository implements Auth
{
public function Register($request)
{
$user = new User([
'name' => $request->input('name'),
'email' => $request->input('email'),
'password' => bcrypt($request->input('password'))
]);
$user->save();
return $user;
}
public function Login($request)
{
$credentials = $request->all();
if (!Authenticate::attempt($credentials))
return response()->json([
'message' => 'Unauthorized'
], 401);
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
$token->save();
return $tokenResult;
}
}
This is happened because the controller is trying to get the user data and create a token based on that.
In your case (happened to me too), there was a user variable which pointing the request to get the user credential while the user data is unknown because the user is not yet logged in.
To be clear, please take a look at your code within this line:
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
To fix that, change the line of $user = $request->user() to this:
$user = User::whereEmail($request->email)->first();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;

How to remove Laravel Auth Hashing (to replace it by mysql hashing)?

I added registration, and I don't want to using laravels hash but mysql Hash (because I want existing users to still be able to connect).
So i do it step by step and for now I just try to register and then login without any hashing. The credentials are correct in my table but I get
"message":"The given data was invalid.","errors":{"email":["These credentials do not match our records."]}
I tried setting it in LoginController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
public function username()
{
return 'email';
}
public function password()
{
return 'email';
}
public function setPasswordAttribute($password){
$this->attributes['password'] = $password;
}
public function Login(Request $request)
{
if(Auth::attempt(['email' => $request->email, 'pwd' => $request->password, 'password' => $request->password])){
$user = Auth::user();
$username = $user->nom;
return response()->json([
'status' => 'success',
'user' => $username,
]);
} else {
return response()->json([
'status' => 'error',
'user' => 'Unauthorized Access'
]);
}
}
}
I guess I should overwrite another function, but can't find out which one.
Could you please give me some help?
Altough what you're trying to achieve is considered unsecure, to remove Laravel's hashing for password, you need to add this to your User model :
public function setPasswordAttribute($password){
$this->attributes['password'] = $password;
}
and not in your controller, and be sure to remove the brcypt() methods in your RegisterController
To add your MySQL own hashing methods, update your controller to insert a RAW query while creating a user upon registration

Laravel : transforming a request into another

I want to log my users as soon as they register. here's my UserController's code (which works) :
<?php
namespace App\Http\Controllers;
use App\Http\Requests\Login;
use App\Http\Requests\Register;
use App\User;
class UserController extends Controller
{
public function register(Register $request)
{
User::create($request->all());
$loginRequest = new Login();
$loginRequest['email'] = $request->get('email');
$loginRequest['password'] = $request->get('password');
return $this->login($loginRequest);
}
public function login(Login $request)
{
return 'ok';
}
}
I feel I'm doing something ugly with my $loginRequest. Is there a neater way to do the same ? Aka transform my Register request into a Login request ?
You are simply trying to logged in user into his account after the registration so use Auth::login($user)
class UserController extends Controller
{
public function register(Register $request)
{
$user = User::create($request->all());
\Auth::login($user);
}
}
As soon as user register you can use this snippet of code to attempt a login
if (Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
return Redirect::route('dashboard');
}
So the code should be
User::create($request->all());
$loginRequest = new Login();
$loginRequest['email'] = $request->get('email');
$loginRequest['password'] = $request->get('password');
if (Auth::attempt(['email' => $request->get('email'),
'password' => $request->get('password')])) {
return Redirect::route('dashboard');
}

How to check user status while login in Laravel 5?

I have used Laravel Authentication (Quickstart). But I need to check the status of the user (approved/pending). If not approved, then an error will be shown in the login page. I need to know in which file I have to make the change and what is the change. Currently I am working on Laravel 5.3.
You can create a Laravel Middleware check the link for additional info
php artisan make:middleware CheckStatus
modify your middleware to get
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class CheckStatus
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
//If the status is not approved redirect to login
if(Auth::check() && Auth::user()->status_field != 'approved'){
Auth::logout();
return redirect('/login')->with('erro_login', 'Your error text');
}
return $response;
}
}
then add your middleware to your Kernel.php
'checkstatus' => \App\Http\Middleware\CheckStatus::class,
and finally add the middleware to your route
Route::post('/login', [
'uses' => 'Auth\AuthController#login',
'middleware' => 'checkstatus',
]);
I hope it helps
I found a simple solution for this. Artisan create App\Http\Controllers\Auth\LoginController, in this default controller just add this code if you have some conditions to login, for example I have a field state, you posibbly have status, email_status or other.
// Custom code for Auth process
protected function credentials( Request $request )
{
$credentials = $request->only($this->username(), 'password');
$credentials['state'] = 1;
return $credentials;
}
upper answer saves me
if (Auth::attempt(['email'=>$input['email'],'password'=>$input['password'], 'user_status'=>1 ]))
this will check the status
Just Add following method in my LoginController works like charm
protected function authenticated(Request $request, $user)
{
if ($user->yourFirldName != "Active") {
Auth::logout();
return redirect('/login')->with('error', 'Looks Like Your status is InActive');
}
}
I don't agree with upper answer, which will lead to your application performance is very low, and also don't recommend to modify the Laravel's source code.
So you can rewrite getCredentials function to your app\Http\Controllers\Auth\AuthController.php file like this:
<?php
//app\Http\Controllers\Auth\AuthController.php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
//you need add this function
protected function getCredentials(Request $request)
{
$data = $request->only($this->loginUsername(), 'password');
$data['is_approved'] = 1;
return $data;
}
}
then you can use Laravel Authentication (Quickstart) directly.
Hope this will help.
The pinned answer is the best approach.
Just a note: if you are using Laravel 5.8+ you need use:
//Default Auth routes
Auth::routes();
//Override and add middleware
Route::post('/login', [
'uses' => 'Auth\LoginController#login',
'middleware' => 'checkstatus',
]);
Follow the steps...
First add a column in your user table (suppose is_approved)
In App/Http/Controllers/Auth/LoginController file
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password, 'is_approved'=>1])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
Hope this will help
Auth/LoginController
Though it is a long time from the question created date. You can go this way.
Go to Auth/LoginController and add this line.
protected function credentials(Request $request)
{
return [
'email' => $request->email,
'password' => $request->password,
'status' => 1,
];
}
For this to work you have to have a column named 'status' in users table. 1 is for active and 0/2 is for inactive user.
Hope this will work for you.
public function login(Request $request){
if ($request->isMethod('post')) {
$data= $request->all();
$roles=[
'email' => 'required|email|max:255',
'password' => 'required',
];
$customessage=[
'email.required' =>'Email is required',
'email.email' => 'Email is not vaild',
'password.required' => 'Password is required',
];
$this->validate($request,$roles,$customessage);
if(Auth::guard('admin')->attempt(['email'=>$data['email'],'password'=>$data['password'],'status'=>1])) {
return redirect('admin/dashboard');
} else {
Session::flash('error_message','You are not Active by Admin');
return redirect()->back();
}
}
return view('admin.admin_login');
}

Resources