Lumen Custom Authentication with custom Fields and Store in Auth Guard - laravel

I am using lumen for API development. I have an issue in Lumen Custom Authentication.
I want to login a user when his credentials and account_name matches with stored record. In the credentials filed there is not username and password type data.
here my login method
public function login(Request $request)
{
$this->validate($request,[
'data.credentials' => 'required',
'data.account_name' => 'required',
]);
try {
$credentials=$request->data['credentials'];
$account_name=$request->data['account_name'];
$user=User::where('account_name',$account_name)->where('credentials',$credentials)->first();
if($user){
// storing the authenticated user to the guard session
$auth_token=Hash::make($account_name . ":" . $credentials);
// update user auth token
$user->auth_token=$auth_token;
$user->update();
$data="Some Data";
return response()->json([
"auth_token"=> $auth_token,
"data"=>$data,
"request_id"=> uniqid(),
"status"=> "success"
]);
}
} catch (\Exception $e) {
return response()->json(array(
'error' => $e->getMessage(),
'status' => 'failed',
'status_code' => 500
));
}
}
I authenticated user with credentials I want to store that user in guard that can be default guard or custom and want to return auth_token from every response. if I use following code it give me an error.
Auth::guard()->attempt(['credentials'=>$credentials,'account_name'=>$account_name]);
It give an error that attempt_undefined_method. and If I use the following code
Auth::guard()->check(['credentials'=>$credentials,'account_name'=>$account]);
it returns the false value and do not store user in guard. I want such type of response from every request where I applied auth middleware
return response()->json([
"auth_token"=> auth()->user()->auth_token,
"data"=>$data,
"request_id"=> uniqid(),
"status"=> "success
]);
following is my AuthMiddleware.php code
$header=$request->header('Auth-Token');
if(Auth::guard('api')){
// we can use $user variable for further :)
return $next($request);
}

Related

Laravel JWT ATUH can't maintain user to other page

AS see my captures,
i made jwt login page.
it makes jwt token but after that,
go home and check user's name but Auth::user() is null
if i dd($user) on api/auth/login page, user's info appears
but go home page and trying to check user's info, there is only null page
here is my full code.
https://github.com/sksmsWKd/MetaComposerProto
would you do me a favor?
this is my login function on AuthController.
it makes jwt token well but can't maintain user's login to other page...
$input = $request->only('email', 'password');
$jwt_token = null;
if (!$jwt_token = JWTAuth::attempt($input)) {
return response()->json([
'success' => false,
'message' => 'Invalid Email or Password',
], Response::HTTP_UNAUTHORIZED);
}
return response()->json([
'success' => true,
'token' => $jwt_token,
]);

Laravel 8 reset password in PWA

I am trying to establish a password reset system in a Laravel + SPA environment with Vuejs. Except for the form that starts the process ('I have forgotten my password'), the rest of the actions I want to be carried out in the standard Laravel way, outside the spa and using Laravel Auth. So I have:
web.php
//This sends a custom email notification.
Route::post('/forgot-password', 'UserController#reestablecerPassword')->middleware('guest')->name('password.email');
//Shows the standard view auth.passwords.reset, when we can reset password values.
Route::get('/reset-password/{token}', function ($token) {
return view('auth.passwords.reset', ['token' => $token]);
})->middleware('guest')->name('password.reset');
//Route to custom method in order to receive and process the previous form
Route::post('/reset-password', 'UserController#procesarReestablecerPassword')->middleware('guest')->name('password.update');
//this returns a simple view where it is reported that the password has been changed
Route::get('/changedpassword', function () {
return view('changedpassword');
})->name('changedpassword');
Methods in UserController.php
//Handles the response by email and the response to the front-end to inform that the email has been sent
public function reestablecerPassword(Request $request){
$request->validate(['email' => 'required|email']);
$status = Password::sendResetLink(
$request->only('email')
);
Log::info('status:');
Log::info($status);
$status == 'passwords.sent' ? $respuesta = response('OK', 200) : $respuesta = response('KO', 400);
return $respuesta;
}
//Process the request that contains the form data and reset the password. The program flow does not execute this method in production, the log is not written
public function procesarReestablecerPassword(Request $request) {
Log::info('entra a procesarReestablecerPassword con estos valores en la petición:');
Log::info($request);
$request->validate([
'token' => 'required',
'email' => 'required|email',
'password' => 'required|min:8|confirmed',
]);
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user, $password) use ($request) {
$user->forceFill([
'password' => Hash::make($password)
])->save();
$user->setRememberToken(Str::random(60));
event(new PasswordReset($user));
}
);
return $status == Password::PASSWORD_RESET
? redirect()->route('changedpassword')->with('status', __($status))
: back()->withErrors(['email' => [__($status)]]);
}
The issue appears when we submit the reset-password view form, when I get the error:
The GET method is not supported for this route. Supported methods: POST.
Observing the operation in the web browser:
In the local environment, where the operation is correct, two actions happen after pressing the submit button of the form:
A first POST type is sent with the form data. Such as:
https://appname.com/reset-password
A 'Location' header is received to redirect to a second URL via GET that includes the user token. Being of type:
https://appname.com/reset-password/jkladjfñl9iu08adDjfjnnakRfpaiw
Well, in the production environment, this token is not found in the url received in the Location header (I don't know why this occurs)
Thanks in advance.

Laravel test fails, but works on postman

I have a test for a user logging out and having their token deleted.
use RefreshDatabase;
public function setUp() :void {
parent::setUp();
\Artisan::call('migrate',['-vvv' => true]);
\Artisan::call('passport:install',['-vvv' => true]);
\Artisan::call('db:seed',['-vvv' => true]);
}
...
/**
* #test
*/
public function a_user_has_tokens_removed_when_logged_out()
{
// login
$this->withoutExceptionHandling();
$user = factory('App\User')->create();
$response = $this->post('/api/login', [
'username' => $user->email,
'password' => 'password'
]);
$token = json_decode($response->getContent())->access_token;
$this->assertTrue(!$user->tokens->isEmpty());
// logout
Passport::actingAs($user, ['*']);
$logout = $this->json('POST', 'api/logout')->withHeaders([
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token
]);
$this->assertTrue($user->tokens->isEmpty());
}
First I'm creating a user and logging them in so a token is created and related to their user account.
I'm asserting that the token exists after hitting the login route, which passes.
Then I'm calling the logout route which will delete all the tokens the user has:
public function logout() {
auth()->user()->tokens()->each(function($token, $key) {
$token->delete();
});
return response()->json('Logged out successfully', 200);
}
routes/api.php
Route::middleware('auth:api')->post('logout', 'AuthController#logout');
This assertion on the test above is failing:
$this->assertTrue($user->tokens->isEmpty());
If I do a dd($user->tokens); before the assertion to check what's going on, the token shows up - it still exists.
But If I hit this api/logout route with Postman, which has everything stored in MySQL, all the tokens are being deleted successfully.
I don't understand what's going on and why this test is failing. Or rather, I don't understand why the $token->delete() doesn't work on the test, but does via Postman. What's different?
Before executing the assert, reload the user model relations via $user->fresh(), to ensure the deleted relations are reflected in the instance.
I don't know why, but within the testing context, this is not done automatically.

Why Auth::check() returns true after logout ? Passport

So I made Authentication using passport, everything worked fine until I logged user out. My paths are protected via auth:api guard so after logging out I can't access any functions, however my frontend is rendered via react based on Auth:check() value and it stays true after logging out. Therefore I am able to get into admin dashboard without any permissions, which is a bug and I can't find a solution to fix it.
This is my log out function:
public function logout()
{
if (Auth::check()) {
DB::table('oauth_access_tokens')
->where('user_id', Auth::user()->id)
->update([
'revoked' => true
]);
return response(['check' => Auth::check()]); // I get true after logging out
}
return response(['check' => Auth::check()]);
}
This is my login and register functions:
public function register(Request $request){
$validatedData = $request->validate([
'name' => 'required|max:55|unique:users',
'password' => 'required'
]);
$validatedData['password'] = bcrypt($request->password);
$user = User::create($validatedData);
$accessToken = $user->createToken('authToken')->accessToken;
return response()
}
public function login(Request $request)
{
$loginData = $request->validate([
'name' => 'required',
'password' => 'required'
]);
$a = auth()->attempt($loginData, true);
if(!$a) {
return response(['message'=>'Invalid credentials');
}
$accessToken = auth()->user()->createToken('authToken')->accessToken;
return response()->json($accessToken);
}
What have I missed?
The reason that Auth::check() returns true is the user is set on the auth service. You are only revoking the access token, meaning that the user will be logged out from the next request.
You can solve this one of two ways
1) Assume that the any call to the logout route will result in the user being logged out, irrespective of the logic performed. For example, you could make the call and then clear the access token in your frontend (or perform whatever other logout logic).
2) You can call Auth::logout() in your code, which will set the current user on the authentication service to null resulting in Auth::check() returning false.

Check If user has a role In Laravel 5.5

I'm using entrust package to manage roles and I have used passport for authentication since it is API's.
Actually what I need is want to check user has a role,
I have tried with below code but it doesn't work
public function Adminlogin()
{
if(Auth::attempt(['email' => request('email'), 'password' => request('password')]))
{
$user = Auth::user();
if($user->hasRole('admin'));
{
$success['token'] = $user->createToken('MyApp')->accessToken;
return response()->json(['success' => $success], $this->successStatus);
}
return response()->json(['error'=>'Abort'], 403);
}
else
{
return response()->json(['error'=>'Unauthorised'], 401);
}
}
I want to generate access token only if user has admin role,If user has no role admin then show abort message.
if(Auth::user()->hasRole('admin'))
should work.
But you don't explain what is not working in your case so...

Resources