On Axios request laravel auth attemp session part not working - php

am making a login screen using bootstrap model and when I request using axisos call to server everything working fine but when the response came and I refresh page laravel session part not working
here is my code in controller :
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function showLoginForm()
{
return view('login');
}
//use AuthenticatesUsers;
public function login(Request $request)
{
$validator = Validator::make($request->all(), [
'phone' => 'required|numeric|',
'password' => 'required|min:6',
]);
if ($validator->fails()) {
// return redirect()->back()->with('errors',$validator->errors())->withInput($request->only('phone', 'remember'));
return response()->json(['success'=>false,'error'=>$validator->errors()], 403);
}
// Attempt to log the user in
if (Auth::guard('web')->attempt(['phone' => '+91'.$request->phone, 'password' => $request->password], $request->remember)) {
// if successful, then redirect to their intended location
return response()->json(['success'=>true,'message'=>'login successfully'], 200);
}
// if unsuccessful, then redirect back to the login with the form data
//dd('auth fail am here');
//return redirect()->back()->withErrors(['Invalid Phone Or Password'])->withInput($request->only('phone', 'remember'));
return response()->json(['success'=>false,'error'=>'Invalid Phone Or Password'], 401);
}
/**
* Where to redirect users after login.
*
* #var string
*/
// protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function logout()
{
Auth::guard('web')->logout();
return redirect('/login');
}
}
this is my axios request:
axios.post(process.env.MIX_BASEURL+'/login', vm.loginDetails)
.then(response => {
event.target.disabled = true;
console.log(response);
// console.log(response.config.method)
if (response.status == 200){
alert('login success')
vm.loginsuccess = true
$("#phone").addClass("is-valid");
$("#password").addClass("is-valid");
vm.successlogin=response.data.message
toastr["success"](vm.successlogin);
if(response.status===200){
let intended=response.data.intended;
alert(intended);
//return;
window.location.href = intended;
this.closeModal();
}
}
})
.catch(error => {
console.log('am here in error');
console.log(error.response);
var errors = error.response
console.log(error.response)
///IF EMPTY FIELDS FOUND///
if (errors.status === 403) {
//alert('empty fields Forbidden')
//alert(errors.data.error.phone[0])
if (errors.data) {
if (errors.data.error.phone) {
vm.errorsPhone = true
$("#phone").addClass("is-invalid");
vm.PhoneError = _.isArray(errors.data.error.phone) ? errors.data.error.phone[0] : errors.data.error.phone
//alert(vm.PhoneError)
toastr["error"](vm.PhoneError);
}
if (errors.data.error.password) {
vm.errorsPassword = true
$("#password").addClass("is-invalid");
vm.passwordError = _.isArray(errors.data.error.password) ? errors.data.error.password[0] : errors.data.error.password
//alert(vm.passwordError)
toastr["error"](vm.passwordError);
}
}
}
if (errors.status === 401) {
//alert('invalid login details')
vm.errorslogin = true
vm.loginerror=errors.data.error
//alert(vm.loginerror)
toastr["error"](vm.loginerror);
}
});
}
**what i have try :**when i click on login my data is gone auth attemp successfull i got 200 and my msg as i set in response then i call to location reload (my first try and fail) it reload page for new data but session data not coming in my blade template

Related

Laravel: using throttle in a custom Login controller

This is my login controller function
use ThrottlesLogins;
protected $maxLoginAttempts = 3;
protected $lockoutTime = 300;
public function login(Request $request)
{
if ($this->hasTooManyLoginAttempts($request))
{
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$validator = Validator::make(Input::all() , ['credential' => 'required|min:2|max:255', 'password' => 'required|string|min:8', ]);
$cred = $request->credential;
$pw = $request->password;
$remember = (Input::has('remember')) ? true : false;
if (filter_var($cred, FILTER_VALIDATE_EMAIL))
{
if (Auth::guard('customers')->attempt(['email' => $cred, 'password' => $pw, 'verified' => 1], $remember))
{
return redirect()->route('front');
}
else
{
return redirect()->route('customer-login-page')->with('error', 'Your credentials do not match');
}
}
else
{
if (Auth::guard('customers')->attempt(['contact' => $cred, 'password' => $pw], $remember))
{
return redirect()->intended(route('front'));
}
else
{
return redirect()->route('customer-login-page')->with('error', 'Your credentials do not match');
}
}
}
protected function hasTooManyLoginAttempts(Request $request)
{
return $this->limiter()->tooManyAttempts(
$this->throttleKey($request), $this->maxLoginAttempts, $this->lockoutTime
);
}
It's not working. I've tried failed login attempts more that 3 times and still not getting throttled. AND
Even when I post the correct credentials, the login and redirect works but when I check the request I get a
302 FOUND error
in the network tab
You need to let the trait know that you are performing a login attempt by calling $this->incrementLoginAttempts($request) (see code). You can place this call right after your existing throttle check:
if ($this->hasTooManyLoginAttempts($request))
{
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$this->incrementLoginAttempts($request);
// other code
Try
use Illuminate\Foundation\Auth\ThrottlesLogins;
Instated of
use ThrottlesLogins;

How to rewrite a method for using with AJAX?

I have a trait which handle password restoring logic:
public function reset(Request $request)
{
$this->validate($request, $this->rules(), $this->validationErrorMessages());
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($response)
: $this->sendResetFailedResponse($request, $response);
}
protected function rules()
{
return [
'token' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed|min:6',
];
}
protected function sendResetFailedResponse(Request $request, $response)
{
return redirect()->back()
->withInput($request->only('email'))
->withErrors(['email' => trans($response)]);
}
I want to use it with AJAX calls. How should I rewrite sendResetFailedResponse()?
When I use this logic without AJAX and if validation fails on rules() I simply get an error response with 422 status code. But if validation fails while on checking token validity (reset()) - there are no errors with status code in return.
My AJAX is like
axios.post('/password/reset', {
//data to send
})
.then((response) => {
...
})
.catch((error) => {
//I can catch errors which are returning from rules() fail
//I want to catch non-valid token error here too
});
I tried to override
protected function sendResetFailedResponse(Request $request, $response)
{
return response(['email' => trans($response)]);
}
but this code returns token error after AJAX .catch()
I just do this in the reset method and it works pretty good.
public function reset(Request $request)
{
$this->validate($request, $this->rules(), $this->validationErrorMessages());
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request), function ($user, $password) {
$this->resetPassword($user, $password);
}
);
if ($request->ajax()){
if ($response == Password::PASSWORD_RESET) {
return response()->json(['message' => 'Success'],200);
} else {
return response()->json(['error' => 'Please try again'], 422);
}
}
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $response == Password::PASSWORD_RESET
? $this->sendResetResponse($response)
: $this->sendResetFailedResponse($request, $response);
}
Hope this helps

Unable to authenticate with invalid token error in dingo/api with jwt-auth

I'm using dingo/api (that has built-in support for jwt-auth) to make an API.
Suppose this is my routes :
$api->group(['prefix' => 'auth', 'namespace' => 'Auth'], function ($api) {
$api->post('checkPhone', 'LoginController#checkPhone');
//Protected Endpoints
$api->group(['middleware' => 'api.auth'], function ($api) {
$api->post('sendCode', 'LoginController#sendCode');
$api->post('verifyCode', 'LoginController#verifyCode');
});
});
checkPhone method that has task of authorize and creating token is like :
public function checkPhone (Request $request)
{
$phone_number = $request->get('phone_number');
if (User::where('phone_number', $phone_number)->exists()) {
$user = User::where('phone_number', $phone_number)->first();
$user->injectToken();
return $this->response->item($user, new UserTransformer);
} else {
return $this->response->error('Not Found Phone Number', 404);
}
}
And injectToken() method on User Model is :
public function injectToken ()
{
$this->token = JWTAuth::fromUser($this);
return $this;
}
Token creation works fine.
But When I send it to a protected Endpoint, always Unable to authenticate with invalid token occures.
The protected Endpoint action method is :
public function verifyCode (Request $request)
{
$phone_number = $request->get('phone_number');
$user_code = $request->get('user_code');
$user = User::wherePhoneNumber($phone_number)->first();
if ($user) {
$lastCode = $user->codes()->latest()->first();
if (Carbon::now() > $lastCode->expire_time) {
return $this->response->error('Code Is Expired', 500);
} else {
$code = $lastCode->code;
if ($user_code == $code) {
$user->update(['status' => true]);
return ['success' => true];
} else {
return $this->response->error('Wrong Code', 500);
}
}
} else {
return $this->response->error('User Not Found', 404);
}
}
I used PostMan as API client and send generated tokens as a header like this :
Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI5ODkxMzk2MTYyNDYiLCJpc3MiOiJodHRwOlwvXC9hcGkucGFycy1hcHAuZGV2XC92MVwvYXV0aFwvY2hlY2tQaG9uZSIsImlhdCI6MTQ3NzEyMTI0MCwiZXhwIjoxNDc3MTI0ODQwLCJuYmYiOjE0NzcxMjEyNDAsImp0aSI6IjNiMjJlMjUxMTk4NzZmMzdjYWE5OThhM2JiZWI2YWM2In0.EEj32BoH0URg2Drwc22_CU8ll--puQT3Q1NNHC0LWW4
I Can not find solution after many search on the web and related repositories.
What is Problem in your opinion?
Update :
I found that not found error is for constructor of loginController that laravel offers :
public function __construct ()
{
$this->middleware('guest', ['except' => 'logout']);
}
because when I commented $this->middleware('guest', ['except' => 'logout']); all things worked.
But if I remove this line is correct?
How should be this line for APIs?
updating my config/api.php to this did the trick
// config/api.php
...
'auth' => [
'jwt' => 'Dingo\Api\Auth\Provider\JWT'
],
...
As I mentioned earlier as an Update note problem was that I used checkPhone and verifyCode in LoginController that has a check for guest in it's constructor.
And because guest middleware refers to \App\Http\Middleware\RedirectIfAuthenticated::class and that redirects logged in user to a /home directory and I did not created that, so 404 error occured.
Now just I moved those methods to a UserController without any middleware in it's constructor.
Always worth reading through the source to see whats happening. Answer: The is expecting the identifier of the auth provider in order to retrieve the user.
/**
* Authenticate request with a JWT.
*
* #param \Illuminate\Http\Request $request
* #param \Dingo\Api\Routing\Route $route
*
* #return mixed
*/
public function authenticate(Request $request, Route $route)
{
$token = $this->getToken($request);
try {
if (! $user = $this->auth->setToken($token)->authenticate()) {
throw new UnauthorizedHttpException('JWTAuth', 'Unable to authenticate with invalid token.');
}
} catch (JWTException $exception) {
throw new UnauthorizedHttpException('JWTAuth', $exception->getMessage(), $exception);
}
return $user;
}

Laravel JWT Auth get user on Login

Is it possible with https://github.com/tymondesigns/jwt-auth
to get the current user? Because right now I can only generate a token (when a user sign in).
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
try {
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['error' => 'could_not_create_token'], 500);
}
return response()->json(compact('token'));
}
You don't need Auth::user();
You can use the toUser method of JWTAuth. Just pass the token as parameter and you will get back the user info:
$user = JWTAuth::toUser($token);
return response()->json(compact('token', 'user'));
For more info, this is the toUser method:
/**
* Find a user using the user identifier in the subject claim.
*
* #param bool|string $token
*
* #return mixed
*/
public function toUser($token = false)
{
$payload = $this->getPayload($token);
if (! $user = $this->user->getBy($this->identifier, $payload['sub'])) {
return false;
}
return $user;
}
You can get logged user data.
$credentials = $request->only('code', 'password', 'mobile');
try {
// verify the credentials and create a token for the user
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// something went wrong
return response()->json(['error' => 'could_not_create_token'], 500);
}
$currentUser = Auth::user();
print_r($currentUser);exit;
You can also use JWTAuth::user() method.
The user() method call is returned in the toUser() method, which itself is an alias for authenticate() method which authenticates a user via a token. If the user is already authenticated, there is no need to authenticate them again (which toUser() does), instead user() method can be used to get the authenticated user.
// $token = JWTAuth::attempt($credentials) was successful...
$user = JWTAuth::user();
return response()->json(compact('token', 'user'));
It works fine for me (laravel 5.7)
U must post token to me function and will return user
use Tymon\JWTAuth\Facades\JWTAuth;
public function me(Request $request)
{
$user = JWTAuth::user();
if (count((array)$user) > 0) {
return response()->json(['status' => 'success', 'user' => $user]);
} else {
return response()->json(['status' => 'fail'], 401);
}
}
try this (it works fine with laravel 5.6,5.7):
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
// code to generate token for user with email testuser#gmail.com
$user=User::where('email','=','testuser#gmail.com')->first();
if (!$userToken=JWTAuth::fromUser($user)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
return response()->json(compact('userToken'));
just need to return inside the specified route middleware
The route that you defined api route
Route::group(['middleware' => 'jwt.auth'], function () {
Route::post('/user', function (Request $request) {
try {
$user = \Illuminate\Support\Facades\Auth::user();
return $user;
} catch (\Tymon\JWTAuth\Exceptions\UserNotDefinedException $e) {
return '$user';
}
});
});
You can get the current user related to token using :
$user = JWTAuth::setToken($token)->toUser();
In Laravel 7.2 if none of the above works use like this to retrive the user:
$credentials = request(['email', 'password']);
if (! $token = auth('api')->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$user = auth('api')->user();
dd($user);
Solution for who are all struggle validate the user and token and then guard
Problems that i face
Jwt does not return any user even i put currect token
return null
$user = JWTAuth::user(); //getting null
return false
$user = JWTAuth::parseToken()->authenticate();
return false
auth()->user()
Solution to check
Before Going to solution middleware and your route guard is matter so keep in mind
Guard setting config/auth.php
'guards' => [
'website_admin' => [
'driver' => 'jwt',
'provider' => 'website_admin',
],
]
Provider
'providers' => [
'super_admin' => [
'driver' => 'eloquent',
'model' => App\Website_super_admin_auth::class,
],
]
Middleware (must)
<?php
namespace App\Http\Middleware;
use Closure;
use JWTAuth;
use Exception;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
class JwtMiddleware extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
try {
$user = JWTAuth::parseToken()->authenticate();
} catch (Exception $e) {
if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
return response()->json(['status' => 'Token is Invalid']);
}else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
return response()->json(['status' => 'Token is Expired']);
}else{
return response()->json(['status' => 'Authorization Token not found']);
}
}
return $next($request);
}
}
Route(should specify middleware with guard)
Route::group(['prefix' => 'super_ad', 'middleware' => ['jwt.verify','auth:super_admin']], function()
{
Route::get('/test', function (){
// $user = JWTAuth::parseToken()->authenticate(); <-------check user here
$user=auth()->user();
// return $user;
});
})
$user = JWTAuth::setToken($token)->toUser();
Auth::login($user, $remember = true);
public function user(Request $request){
/// get user details from token
$user = JWTAuth::toUser($this->bearerToken($request));
// get payloads in the token
$payload = JWTAuth::getPayload($this->bearerToken($request));
}
public function bearerToken($request)
{
$header = $request->header('Authorization', '');
if (Str::startsWith($header, 'Bearer ')) {
return Str::substr($header, 7);
}
}

Laravel - How to logout and display logout page when user manually enter unauthorized URL

I am beginner of laravel. I am using Role and permission concept for multiple user. If user manually enter URL which is not allow to that user then I want to logout that user.
I have successfully logout the user but display logout page in content area part not single page of login.
Please help me .
Thanks in advance ....
image snapshot
enter image description here
This is my ACL Code -
public function handle($request, Closure $next, $permission = null)
{
if ($request->getSession()->has('user')) {
$userObj = new \App\User;
if ($userObj->canAccess($request->getSession()->get('user')[0]['userPerm'], $permission)) {
return $next($request);
}
else{
redirect('logout')->withErrors(array('mst_error' => 'Unauthorized Access!'))->send();exit;
}
}
return $request->isXmlHttpRequest() ?
response(json_encode(array('session_logout' => true)), 401) :
redirect('login')->withErrors(array('mst_error' => 'You don\'t have any active session. Please login again'));
}
I have resolved :)
This is my handle function
public function handle($request, Closure $next, $permission = null)
{
if ($request->getSession()->has('user')) {
$userObj = new \App\User;
if ($userObj->canAccess($request->getSession()->get('user')[0]['userPerm'], $permission)) {
return $next($request);
}
else{
return response()->json(array('mst_error'=>'Unauthorized Access.'),401);
}
}
return $request->isXmlHttpRequest() ?
response(json_encode(array('session_logout' => true)), 401) :
redirect('login')->withErrors(array('mst_error' => 'You don\'t have any active session. Please login again'));
}
This is my Ajax Request -
$.ajax({
url:url,
data:data,
statusCode: {
401: function(res){
location.href = "unauthorized";
}
}
}).done(function(result){console.log(result);
$('#section-content').html(result);
});
This is my unauthorized function in Auth Controller
protected function unauthorized_logout (Request $request) {
if ($request->getSession()->has('user')) {
$request->getSession()->flush();
}
Session::flash('error','Unauthorized Access!');
return redirect('/');
}

Categories