JWT custom authentication in Laravel 5 - php

i have made a custom model class for authentication in Laravel 5. I already changed the auth.php and jwt.phpattributes that represents User class.
The JWT is working, but, when i try to login it returns the invalid credentials error, even when i have the register in my database.
I've been thinking it should be something about encryptation, so i tried to encrypt my password and i have updated with the hash de password field in DB (it wasn't encrypted yet). But it stills bring me the credentials error.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\AuthRequest;
use App\Http\Requests;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
class AuthController extends Controller
{
public function login(AuthRequest $request) {
$credentials = [
'email' => $request->input('email'),
'password' => bcrypt($request->input('password'))
];
try {
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
return response()->json(['error' => 'could_not_create_token'], 500);
}
return response()->json(['token' => $token]);
}
}
Someone knows how i can solve this problem?

I've solved this. It was a problem between my stored password and my parameter password. I took off the bcrypt and put the field encrypted in database.

Related

Failure to create Laravel Sanctum token after user has been registered using a One Time Pin (OTP)

I am trying to create a login token for a user after they register on my application and have verified their mobile device using an OTP sent via sms. The problem is that, when a user logs in, the token is created perfectly. However, when I try to create this token on registration, no token is generated. When a user registers, I want to immediately log them into my app.
Note: This is an app using an API. The login logic works perfectly.
Question Is there anywhere I might be missing it. Have been debugging but no success.
<?php
namespace App\Http\Controllers\Admin;
use App\Models\User;
use App\Exceptions\Handler;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use App\Http\Resources\LoginResource;
class RegisterController extends Controller
{
public function verifyOTP(Request $request){
$validate = Validator::make($request->all(), [
'otp' =>'required|digits:4',
'cellphone' =>'required|digits:10',
]);
if ($validate->fails()){
return response($validate->errors(), 400);
}
$user = DB::table('users')
->where('cellphone', $request->cellphone)
->where('otp', $request->otp)
->first();
if( !$user ){
return response('Wrong OTP. Try again.', 400);
}else{
$updatedUser = DB::table('users')
->where('cellphone', $request->cellphone)
->update([
'status' => 1,
'otp' => NULL,
'account_verified' => 1,
]);
//allocate the user with an authentication token
$loggedInUser = new LoginResource($user);
/******THE FOLLOWING LINE IS THE ONE WITH THE PROBLEM WHERE THE TOKEN IS NOT BEING CREATED. SAYS UNDEFINED METHOD createToken******/
$token = $user->createToken('registration-login-token');
return response([
'user' => $loggedInUser,
'token' => $token->plainTextToken,
], 200);
}
}
}
The error i get is
Error: Call to undefined method stdClass::createToken() in file .../app/Http/Controllers/Admin/RegisterController.php on line 78
Instead of DB you have to use Eloquent Model so use User model instead of DB in below Query :
$user = DB::table('users')
->where('cellphone', $request->cellphone)
->where('otp', $request->otp)
->first();

Laravel - Auth::attempt does not return correct response

Here is my login controller. Like this it does not work:
<?php
namespace App\Http\Controllers;
use App\Account;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function authenticate(Request $request)
{
$credentials = array(
'email'=> $request->email,
'password'=> hash('sha512', $request->password)
);
if (Auth::attempt($credentials)) {
echo "Login is valid";
} else {
echo "IT is not valid login!";
}
var_dump($credentials);
}
}
However like this it works:
<?php
namespace App\Http\Controllers;
use App\Account;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function authenticate(Request $request)
{
$credentials = array(
'email'=> $request->email,
'password'=> hash('sha512', $request->password)
);
if (Account::where($credentials)) {
echo "Login is valid";
} else {
echo "IT is not valid login!";
}
var_dump($credentials);
}
}
Here is how I create the account:
$account = new Account();
$account->email = $request->email;
$account->password = hash('sha512', $request->password);
$account->name = $request->firstName;
$account->lastname = $request->lastName;
$account->country = $request->country;
$account->dob_day = $request->dobDay;
$account->dob_month = $request->dobMonth;
$account->dob_year = $request->dobYear;
$account->save();
Here is my auth.php config file: https://pastebin.com/VqPCNsYC
Why Auth::attempt is not returning correct response?
I am sure data is given and hashed correctly because of Account::where($credentials) this check returns Login is valid.
I am new to Laravel. Can you help me out?
IMHO there is a bit of confusion in your code:
1) Account::where($credentials) is always true because it returns an instance of Illuminate\Database\Eloquent\Builder so you always get "Login is valid" with every input you have.
2) Auth::attempt($credentials) does not attempt to retrieve the User with all the credentials provided but it explicit removes the password key from the where it uses to get the User model (you can see that in the retrieveByCredentials() function in Illuminate\Auth\EloquentUserProvider). After it has retrieved the User it checks that the password provided in the login input matches the hash of the password it has stored in the database.
3) You don't need to hash the password, it is not used to retrieve the user as per point 2 (BTW each time you hash a password the hash is different so you cannot use it in a where like you tried), so you have to write this:
$credentials = array(
'email'=> $request->email,
'password'=> $request->password
);
4) Laravel does not use hash('512',..) to hash a password in the register controller, the supported driver for hashing are; bcrypt, argon, argon2id, and you can change it in config/hashing.php. Laravel uses Hash::make() in the register controller, if you have changed this good luck, you have to change also the way the provider checks the password (see Illuminate\Auth\EloquentUserProvider). But this should be another question.
I hope this helps.
To compare a password against the one stored in the database (a hashed one) you don't need to hash it. Just use the un-hashed version of the password:
public function authenticate(Request $request)
{
$credentials = array(
'email'=> $request->email,
'password'=> $request->password, // <----
);
if (Auth::attempt($credentials)) {
echo "Login is valid";
} else {
echo "IT is not valid login!";
}
var_dump($credentials);
}
Under the hood Laravel will hash the password and compare it against the ones in the database.
According to the docs
you need to provides the simple password only in the validation.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/**
* Handle an authentication attempt.
*
* #param \Illuminate\Http\Request $request
*
* #return Response
*/
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
if (Account::where($credentials)) {
echo "Login is valid";
} else {
echo "IT is not valid login!";
}
var_dump($credentials);
}
Now it will provide you the desired output.

Why api route cannot use Auth::logout laravel

Now, I'm using api.php route for requests from Axios on VueJS , And I need to logout from Auth::guard('web')->logout(); command but, at the moment, I cannot do this.
routes/api.php
Route::group([ 'prefix' => 'v1/auth', 'middleware' => 'jwt'], function () { //
Route::get('me', 'Auth\UserController#me');
Route::get('gg', 'Auth\UserController#test');
});
app/Http/sMiddleware/JwtMiddleware.php
<?php
namespace App\Http\Middleware;
use Closure;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Tymon\JWTAuth\Exceptions\JWTException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Auth;
class RefreshToken extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
try
{
if (! $user = JWTAuth::toUser(JWTAuth::getToken()))
{
return response()->json([
'code' => 101, // means auth error in the api,
'response' => 'not authenticate' // nothing to show
]);
}
}
catch (TokenExpiredException $e)
{
// If the token is expired, then it will be refreshed and added to the headers
try
{
$refreshed = JWTAuth::refresh(JWTAuth::getToken());
header('Authorization: Bearer ' . $refreshed);
}
catch (JWTException $e)
{
return response()->json([
'code' => 103, // means not refreshable
'response' => 'token jwt exception' // nothing to show
]);
}
}
catch (JWTException $e)
{
Auth::guard('web')->logout(); // here
return response()->json([
'code' => 101, // means auth error in the api,
'response' => 'jwterror' // nothing to show
]);
}
return $next($request);
}
}
But when i migrated from api.php to web.php. I can use Axios to post for logout
Please, tell me how to use Auth::logout in api route file.
Sorry I'm not good at english.
Logout is implemented with the session driver, and unlike there web guard, the api guard is using a token driver not session driver.
Basically, the user is not logged into the API, but WEB part of your application.
In the api; find a way to invalidate/expire the token so that the user with that token can no longer access the api resources.
try {
JWTAuth::invalidate($request->input('token'));
return response()->json(['success' => true, 'message'=> "You have successfully logged out."]);
} catch (JWTException $e) {
// something went wrong whilst attempting to encode the token
return response()->json(['success' => false, 'error' => 'Failed to logout, please try again.'], 500);
}
Web logout
Session Logout

How to login with hash class in Laravel 5.1

I want use hash class for hash my passwords.
because I want slat password with My policy.
I have controller like this:
public function postLogin(Request $request)
{
$rules = array(
'username' => 'required',
'password' => 'required|min:8'
);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)
->withInput();
} else {
$user=User::where('username',$request['username'])->where('group_id',1)->get()->toArray();
$password=new PasswordController;
$request['password'] = $password->create_password_str($request['username'],$request['password']);
if(isset($user[0]['password'])&&Hash::check($request['password'], $user[0]['password'])){
return redirect('/dashboard');
} else {
return view('auth.login')->with('flag',5);
}
}
}
I use username after login like this
{{Auth::user()->username}}
show me error
Trying to get property of non-object
I add this code before redirect but dont work.
Auth::login($request['username']);
Because you do not use the laravel builtin function so it did not store the user in a SESSION and it throws an error while you try to fetch a user data which actually does not exists. Here's how to authenticate with laravel auth attempt function
if( Auth::attempt(['username' => $username, 'password' => $password]))
{
//redirect to dashboard
} else
{
//invalid credentials
}
Note : Even you do not need to convert your password to hash. laravel is intelligent enough to convert it to hash.
Update: If you want to use custom salt for your project you could checkout this link.

Can not perform login opreation in laravel 5

I'm trying to login user in my application ,but i can't login.
I'm trying many way to resolve this issue but still not fixed.
Please tell me where I'm wrong .
Error is--
Call to a member function attempt() on a non-object
ControllePage--
<?php
namespace App\Http\Controllers;
use DB;
use Route;
use User;
use Hash;
use Auth;
use Input;
use Validator;
use Authenticatable;
use Redirect;
use Illuminate\Http\Request;
class UsersController extends BaseController
{
/**
* Perform validations on user data
* Hash Password
* Create
* #return Response
*/
public function loginUserAuth() {
$rules = array(
'email' => 'required|email', // make sure the email is an actual email
'password' => 'required|min:5' // password can only be alphanumeric and has to be greater than 3 characters
);
// run the validation rules on the inputs from the form
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
print_r($validator->messages());
die;
return Redirect::to('/login')
->withInput(Input::except('password')) // send back the input (not the password) so that we can repopulate the form
->with('errors',$validator->messages());
} else {
$userdata = array(
'email' => Input::get('email'),
'password' => Hash::make('password')
);
// attempt to do the login
if (Auth::user()->attempt($userdata,true)) {
// validation successful!
// redirect them to the secure section or whatever
// return Redirect::to('secure');
// for now we'll just echo success (even though echoing in a controller is bad)
print_r("error");
die;
return Redirect::intended('/');
} else {
// validation not successful, send back to form
print_r("error11");
die;
return Redirect::to('/login')->with('loginerrors','Invalid username or password');
}
}
}
Please help.
You don't have an authenticated user yet, so you use:
if (Auth::attempt($credentials)) {...
Not:
if (Auth::user()->attempt($credentials)) {...
http://laravel.com/docs/5.0/authentication#authenticating-users
this error is showing up because you are using Auth::user() which is returning null
try this:-
Auth::attempt($userdata)

Categories