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
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;
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
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;
}
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);
}
}
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('/');
}