I have a really strange behavior and I do not see where it could come from. I built an authentication system with Laravel documentation. When I save a User and try to login from the application, it works fine. However when I do the same thing in my AuthControllerTest, the Auth::attempt fails.
AuthControllerTest.php
<?php
use tests\helpers\Factory;
class AuthControllerTest extends ApiTester
{
use Factory;
public function setUp()
{
parent::setUp();
Artisan::call('migrate');
Route::enableFilters();
Session::start();
}
/*
This test fails
I have a 401 instead of a 200 HTTP response code
*/
/** #test */
public function it_should_log_in_user()
{
User::create([
'email' => 'testing#testing.com',
'password' => 'testing'
]);
$credentials = [
'email' => 'testing#testing.com',
'password' => 'testing'
];
//dd(User::count() // I have 1 record
$this->getJson('login', 'POST', $credentials);
$this->assertResponseOk();
}
/** #test */
public function it_should_throws_exception_if_login_fails()
{
User::create([
'email' => 'testing#testing.com',
'password' => 'testing'
]);
$this->getJson('login', 'POST', [
'email' => 'testing#testing.com',
'password' => 'test'
]);
$this->assertResponseStatus(401);
}
/** #test */
public function it_should_log_out_user()
{
$user = User::create([
'email' => 'testing#testing.com',
'password' => 'password'
]);
$this->be($user);
$this->getJson('logout', 'POST');
$this->assertResponseStatus(204);
}
/**
* Generate Alert mock
* #return array
*/
protected function getStub()
{
return [
];
}
}
AuthController.php
<?php
use Arato\Transformers\UserTransformer;
use controllers\ApiController;
class AuthController extends ApiController
{
protected $userTransformer;
function __construct(UserTransformer $userTransformer)
{
$this->userTransformer = $userTransformer;
}
public function login()
{
$rules = [
'email' => ['required', 'email'],
'password' => ['required', 'alphaNum']
];
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return $this->respondUnauthorized();
}
$userData = [
'email' => Input::get('email'),
'password' => Input::get('password')
];
if (Auth::attempt($userData)) {
return $this->respond([
'data' => $this->userTransformer->transform(Auth::user())
]);
} else {
return $this->respondUnauthorized();
}
}
public function logout()
{
Auth::logout();
return $this->respondNoContent();
}
}
Thank you
Remember that the password is encrypted, so you need to get the password directly from the User instance, like:
$user = User::create([
'email' => 'testing#testing.com',
'password' => Hash::make('testing')
]);
$credentials = [
'email' => $user->email
'password' => $user->password
];
Related
I can save the data to the database just fine. And then I right after the creation I'll login that current user with the email. But it will always be sending a request. What might be the problem here?
class RegisterController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/home';
private $loginProxy;
public function __construct(LoginProxy $loginProxy)
{
$this->loginProxy = $loginProxy;
$this->middleware('guest')->except('logout');
}
function apiRegisterUser(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
return response()->json(array('code' => 406, 'error' => $validator->messages()), 406);
} else {
// Log::channel('abuse')->info('user');
$user = User::create(['name' => $request['name'],
'email' => $request['email'],
'password' => Hash::make($request['password']),
'referral_code' => str_random(10)
]);
$user->updateLastRoute(1);
$credentials = $this->loginProxy->attemptLogin($request['email'], $request['password']);
return response()->json($this->successResponse(200, "Login successfull", $credentials), 200);
}
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}
use auth()->attempt() function i m not sure about loginProxy
but auth()->attempt() this should work
$credentials = [
"email" => $request['email'],
"password" => $request['password']
];
if (auth()->attempt($credentials)) {
return response()->json($this->successResponse(200, "Login successfull", $credentials), 200);
}
I can sign up and details are then added to the database but I can't use info from the database to successfully login. It just brings back the same page with no error messages. This is the UserController code
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use App\Http\Requests;
use Auth;
class UserController extends Controller
public function getSignin()
{
return view('user.signin');
}
public function postSignin(Request $request)
{
$this->validate($request, [
'email' => 'email|required',
'password' => 'required|min:4'
]);
if (Auth::attempt(['email' => $request->input('email'), 'password' => $request->input('password')])) {
return redirect()->route('user.profile');
}
return redirect()->back();
}
```auth file
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',
]);
}
/**
* 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']),
]);
}
}
Probably because you're saving your password with bcrypt, but on Auth::attempt you pass it in a plain text. Try this:
Auth::attempt(['email' => $request->input('email'), 'password' => bcrypt($request->input('password'))])
Started the project again using Laravel's built in login and register system.
How to check if user exists in my table or redirect back with a message using Laravel 5.6?
Type error: Argument 1 passed to Illuminate\Auth\SessionGuard::login() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of Illuminate\Http\RedirectResponse given, called in C:\wamp\www\zainsurgalt\vendor\laravel\framework\src\Illuminate\Foundation\Auth\RegistersUsers.php on line 35
protected function create(array $data)
{
$isEmailExists = Niigem::where('email', $data['email'])->count();
if($isEmailExists){
User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
else{
return Redirect::back()->withErrors(['msg', 'The Message']);
}
}
I Added my Create method here
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Niigem;
use Validator;
use Illuminate\Support\Facades\Redirect;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
use RegistersUsers;
protected $redirectTo = '/home';
public function __construct()
{
$this->middleware('guest');
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
protected function create(array $data){
$validator = Validator::make($data, [
'name' => 'required|string',
'email' => 'required|string|email|exists:niigems',
'password' => 'required|string',
]);
if ($validator->fails()) {
return Redirect::back()
->withErrors($validator)
->withInput();
}
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}
You need to return something when the user is created.
protected function create(array $data)
{
$isEmailExists = Niigem::where('email', $data['email'])->count();
if($isEmailExists){
User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
return ........ you need to return something here
} else {
return Redirect::back()->withErrors(['msg', 'The Message']);
}
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|max:255|unique:users|exists:niigems',
'password' => 'required|min:6|confirmed',
]);
}
protected function create(array $data)
{
User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
I see your are trying to create a new user if they exist in the niigem table. To do it the Laravel way, you have to validate using Laravel's validation class. So, this should work:
protected function create(array $data)
{
$validator = Validator::make($data, [
'name' => 'required|string',
'email' => 'required|string|email|exists:niigem',
'password' => 'required|string',
]);
if ($validator->fails()) {
return Redirect::back()
->withErrors($validator)
->withInput();
}
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
Another way is:
Niigem::firstOrCreate(['email' => 'dummy#domain.com'], ['name'=> $data['name'], 'password' => bcrypt($data['password'])]);
Please use this query you can use both condition as per your need:
$user = Niigem::where('email', '=', Input::get('email'))->first();
if ($user === null) {
// user doesn't exist
}
if ($user !== null)
{
// user doesn't exist
}
I do have a feeling that I need to use Auth:: or something here to link to passes. Am I correct
Issue Line
if($validator->passes())
`
getLoginCredentials
protected function getLoginCredentials(Request $request)
{
$validator = $this->loginValidation($request);
if($validator->passes())
{
return[
'email' => Request::input('email'),
'password' => Request::input('password'),
'type' => 1
];
}else{
return redirect()->back()->withErrors();
}
}
loginValidation
protected function loginValidation($request)
{
$rules = array(
'email' => 'required|email',
'password' => 'required',
);
$this->validate( $request , $rules);
}
I think the actual problem is in the loginValidation method that should return an object. Please, see my code below. I've also changed getLoginCredentials a bit as Request shouldn't be called statically.
protected function getLoginCredentials(Request $request)
{
$validator = $this->loginValidation($request);
if ($validator->passes()) {
return [
'email' => $request->input('email'),
'password' => $request->input('password'),
'type' => 1
];
} else {
return redirect()->back()->withErrors();
}
}
loginValidation
protected function loginValidation(Request $request)
{
$rules = [
'email' => 'required|email',
'password' => 'required',
];
return Validator::make($request->all(), $rules);
}
I have a protected function that I want to use to check my login validation. However I am getting the error
Call to undefined method Illuminate\Database\Query\Builder::loginValidation
Do I have to write a model for my function?
Login Validation:
protected function loginValidation($data)
{
$rules = array(
'fname' => 'required|max:255',
'lname' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
);
return Validator::make($data, $rules);
}
getLoginCredentials
protected function getLoginCredentials(Request $request)
{
$validator = User::loginValidation(Request::all());
if($validator->passes())
{
return[
'email' => Request::input('email'),
'password' => Request::input('password'),
'type' => 1
];
return true;
}else{
return redirect()->back()->withErrors();
}
}
I guess the user model can not see your function. Do composer dump-autoload to see if the changes will reflect. if it does not try a new name and see if it will work.