How add new parameter to check in login Laravel - laravel

In LoginController I override the credentials method, like this:
protected function credentials(Request $request)
{
$credentials = $request->only($this->username(), 'password');
$credentials['status'] = User::STATUS_ACTIVE;
return $credentials;
}
And this work pretty fine. But when a try to add a parameter which is not a column of the Users table I don't know how to check there. Some like this:
protected function credentials(Request $request)
{
$credentials = $request->only($this->username(), 'password');
$credentials['status'] = User::STATUS_ACTIVE;
$credentials['customer-status'] = Customer::STATUS_ACTIVE;
return $credentials;
}
Where can I check if the value is correct? I tried to make an event listener to attempt login, but it doesn't work. My idea is to make an Eloquent query to return an account of customers activities. If more then one, customer-status for this user is true.

If anyone is interested in knowing how I solved it, the explanation is as follows:
Based on this code I found in github: https://gist.github.com/joseluisq/fb84779ea54eaebf54a9d8367117463e
In LoginController.php I override 2 methods(login and sendFailedLoginResponse):
public function login(Request $request)
{
$this->validateLogin($request);
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$this->incrementLoginAttempts($request);
$user = User::where('email', $request->email)->first();
if (!$user) {
return $this->sendFailedLoginResponse($request);
}
$customers = Customer::join('users_customers', 'users_customers.customer_id', 'customers.id')
->where([
['users_customers.user_id', '=', $user->id],
['customers.status', '=', Customer::STATUS_ACTIVE]
])
->count();
if ($customers === 0) {
return $this->sendFailedLoginResponse($request, 'auth.inactive');
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
return $this->sendFailedLoginResponse($request);
}
protected function sendFailedLoginResponse(Request $request, $trans = 'auth.failed')
{
$errors = ['email' => trans($trans)];
if ($request->expectsJson()) {
return response()->json($errors, 422);
}
return redirect()
->back()
->withErrors($errors);
}
Remember yourself to define message on auth.php and set uses needed.
Ps.: I don't use $credentials['customer-status'] = Customer::STATUS_ACTIVE;,
as I thought I would.

Related

Broadcast channels not being registered in Laravel

I've been stuck with Broadcasting on private channel in authentication part. What I have done is, I made custom authEndpoint in Echo server
"authEndpoint": "/broadcastAuth",
Controller:
public function broadcastAuth(Request $request){
$channel = $this->normalizeChannelName($request->channel_name);
$broadcaster = new CustomBroadcaster();
$channelAuth = $broadcaster->verifyUserCanAccessChannel($request, $channel);
if($channelAuth){
return true;
}
return response()->json([
'message' => 'Not allowed'
], 403);
}
I have made a custom broadcaster class that extends Illuminate\Broadcasting\Broadcasters\Broadcaster
so that I can override verifyUserCanAccessChannel method
My verifyUserCanAccessChannel method:
public function verifyUserCanAccessChannel($request, $channel)
{
Log::info($this->channels);
foreach ($this->channels as $pattern => $callback) {
if (! $this->channelNameMatchesPattern($channel, $pattern)) {
continue;
}
$parameters = $this->extractAuthParameters($pattern, $channel, $callback);
$handler = $this->normalizeChannelHandlerToCallable($callback);
if ($result = $handler($request->user(), ...$parameters)) {
return $this->validAuthenticationResponse($request, $result);
}
}
throw new AccessDeniedHttpException;
}
Here I have logged $this->channels to get the registered channels from routes/channel.php
But the result is empty.
Here is my BroadcastServiceProvider:
public function boot()
{
require base_path('routes/channels.php');
}
Here is my channel.php:
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Broadcast::channel('post-comment.{id}', function ($user, $id){
\Illuminate\Support\Facades\Log::info($user);
return true;
});
And I have uncommented both in config/app.php
Illuminate\Broadcasting\BroadcastServiceProvider::class,
App\Providers\BroadcastServiceProvider::class,
What could be the mistake here. Please help me figure this out.
Thank you in advance.

Laravel:Error when Implementing JWT authentication

I am experiencing an error when trying to post the API through Postman to authenticate users in the site.
login function:
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if ($token = $this->guard()->attempt($credentials)) {
return $this->respondWithToken($token);
}
return response()->json(['error' => 'Unauthorized'], 401);
}
the guard function
public function guard()
{
return Auth::guard();
}
The error shown on postman
"message": "Call to undefined method Tymon\\JWTAuth\\Contracts\\Providers\\Auth::guard()",
"exception": "Symfony\\Component\\Debug\\Exception\\FatalThrowableError",
How to solve this?
You can use \JWTAuth::attempt function in order to get token if the user inserts valid email and password like:
....
use Tymon\JWTAuth\Exceptions\JWTException;
....
try {
$token = \JWTAuth::attempt($request->only('email', 'password'));
return $this->respondWithToken($token);
} catch (JWTException $exception) {
return response()->json([
'status' => false,
'data' => null,
'message' => 'Could not create token'
]);
}
EDIT 1
The above answer you submitted is correct.
try replacing Auth::guard() to Auth::guard('api')
public function guard()
{
return Auth::guard('api');
}
For more information there is a similar issue in GitHub for reference
Use a construct method like
public function __construct(){
auth()->setDefaultDriver('api');
}
and your login function like
public function login(){
$credentials = request(['email', 'password']);
if(!$token = auth()->attempt($credentials)){
return response()->json(['error' => 'Incorrect email/password'], 401);
}
return $this->respondWithToken($token);
}
And comment out your guard function
I have faced this problem continuously. But the solution was when I used bcrypt() on the password.
bcrypt($password);
Use dependency injection and inject the Auth interface into your class. Code example below.
From the Tymon package import the Auth interface.
use Tymon\JWTAuth\Contracts\Providers\Auth;
In your constructor
public function __construct(Auth $auth)
{
$this->_authentication = $auth;
}
Then use the "byCredentials" method
if (! $token = $this->_authentication->byCredentials($credentials))
{
return response()->json(['message' => 'Unauthorized'], 401);
}

Retrieve a feedback after connection of an user

When the user is connected and wishes to consult the feedback section, the user see each feedbacks for eachs users. I would like to know if it's possible to limit this?
For example, if the user is jeremy#gmail.com, Jeremy can see only his feedback.
Here is an idea of my code, I thank you in advance for your help.
public function index(Request $request)
{
$user = $request->user();
$feedbacks = Feedback::query()
->when($user->hasRole('admin') !== true, function (Builder $query) use ($user) {
\Auth::user()->load('feedbacks');
$feedbacksForThisUser = \Auth::user()->feedbacks;
})
->when($request->has('search'), function (Builder $query) use ($request) {
$query->join('eleves', 'feedbacks.fk_eleve', '=', 'eleves.id')->orderBy('eleves.nom', 'asc')->where('eleves.nom','like','%'.$request->input('search').'%');
})
->paginate(5);
return view('admin.feedbacks.index', compact('feedbacks'))
->with('display_search', $user->hasRole('admin'));
}
Edit
User Model
public function retours()
{
return $this->hasMany('App\Retour', 'user_id', 'id');
}
User Feedback
public function students(){
return $this->belongsTo('App\Student', 'fk_student');
}
public function feedbacks()
{
return $this->hasManyThrough(
'App\Feedback',
'App\Student',
'fk_seance',
'fk_student',
'id',
'id'
);
}
public function user()
{
return $this->belongsTo('App\User', 'id', 'user_id');
}
And
$table->increments('id');
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->string('instruction', 30);
$table->text('description', 80);
$table->integer('fk_student')->unsigned();
$table->foreign('fk_student')->references('id')->on('students');
Sure. When its a normal user, you can just use feedbacks = \Auth::user()->feedbacks;. This will limit to only the logged in user's feedbacks.
If you want to allow an admin to see all feedbacks, then check for admin, and then provide all. So, for just the user or admin (without the search code) something like this:
public function index(Request $request)
{
if(\Auth::user()->hasRole('admin')){
$feedbacks = Feedback::all();
}else{
\Auth::user()->load('feedbacks');
$feedbacks = \Auth::user()->feedbacks;
}
return view('admin.feedbacks.index', compact('feedbacks'));
}
You can add the search code into either of the if-blocks, depending on how you want to allow users to see the search. You can use when() on the query, but I'll demonstrate with just if to make it easier to understand:
public function index(Request $request)
{
if(\Auth::user()->hasRole('admin')){
if($request->has('search'))
$feedbacks = Feedback::orderBy('nom', 'asc')->where('nom','like','%'.$request->input('search').'%');
else
$feedbacks = Feedback::all();
}else{
\Auth::user()->load('feedbacks');
$feedbacks = \Auth::user()->feedbacks;
}
return view('admin.feedbacks.index', compact('feedbacks'));
}

How to check auth login 3 table laravel?

i have a auth login that i make, which have 3 table to auth as admin, how can i fix this? thx
public function postlogin(Request $request)
{
$admin = DB::table('M_ADMIN')->select(['M_ADMIN.PERNR'])->get();
$user = DB::table('M_HEAD_SALLARY')
->join('M_USER', 'M_USER.PERNR', '=', 'M_HEAD_SALLARY.PERNR')
->where('M_USER.PERNR','LIKE','%'.$admin.'%')
->where('M_HEAD_SALLARY.USRID_LONG',strtoupper($request->USRID_LONG))
->where('M_USER.PASS',$request->PASS)
->first();
return redirect('/login');
}
In your LoginController, you can overwrite the attemptLogin method as follow
public function attemptLogin(Request $request) {
$user = Admin::whereHas('M_HEAD_SALLARY', function($query){
// condition
})->whereHas('M_USER', function($query) {
// condition
});
if (Auth::login($user)) {
// Authentication passed...
}
}

Switching user in laravel 5.4

I am switching users in laravel and I succeeded in that as well but the thing is when I redirect the user to the dashboard after successful login it redirects to login form instead I don't know what am I doing wrong. Here is the code I am using.
public function user_reauthenticate(Request $request) {
$input = Input::all();
$data = User::where('email', $input['email'])->first();
if ($data) {
if (Hash::check($input['password'], $data->password)) {
Session::put('email', $input['email']);
$newuser = Student::find($input['new_user']);
session(['orig_user' => $data->id]);
Auth::login($newuser);
return Redirect::back();
} else {
$response = 'Wrong Credentials';
}
} else {
$response = 'User does not exist';
}
}
Can anyone help me find out the issue?
Edited
You can log in with
Auth::loginUsingId(1);
New edited
// If you have the guard student and multiple auth
$auth = auth()->guard('student');
$objAuth = $auth->loginUsingId($input['new_user']);
//Single Auth
$objAuth = Auth::loginUsingId($input['new_user']);
Add this to your top of the file:- use Illuminate\Foundation\Auth\AuthenticatesUsers;
Afterwards add a if function like below in your already completed code:-
public function user_reauthenticate(Request $request)
{
use AuthenticatesUsers;
$input = Input::all();
$data = User::where('email', $input['email'])->first();
if ($data) {
if (Hash::check($input['password'], $data->password))
{
Session::put('email', $input['email']);
$newuser = Student::find($input['new_user']);
session(['orig_user' => $data->id]);
Auth::login($newuser);
if ($this->attemptLogin($request))
{
return $this->sendLoginResponse($request);
}
}
else
{
$response = 'Wrong Credentials';
}
}
else
{
$response = 'User does not exist';
}
}
After this method override this method as follows:-
protected function authenticated(Request $request, $user)
{
return redirect()->route('dashboard');
}
Check whether your dashboard route is named dashboard or if not name it.

Resources