I'm trying to make an auth system to block any access without login but the authenticated method always loads the login page. I override all methods in AuthenticatesUsers because I changed the users' table name and columns but always seem to end up loading the login page. I can return a view in the authenticated method but these will redirect me to the login page if I try to go to another page.
my DB
my login form
<html>
<head>
<meta name="csrf-token" content="{{ csrf_token() }}">
</head>
<body>
{{ Form::open(['action' => 'Auth\LoginController#login','methode' => 'POST']) }}
{{Form::text('login', old('username') ?: old('email'),['class'=>''.$errors->has('email')||$errors->has('username') ? 'is-invalid' : ''.' form-control' ,'placeholder'=>'Nom d\'utilisateur ou email' ,'required', 'autofocus'])}}
#if ($errors->has('username') || $errors->has('email'))
<span class="invalid-feedback">
<strong>{{ $errors->first('username') ?: $errors->first('email') }}</strong>
</span>
#endif
{{Form::password('mot_de_passe', ['class'=>''.$errors->has('password')? 'is-invalid' : ''.' form-control','placeholder'=>'Mot De Passe' , 'required'])}}
#if ($errors->has('password'))
<span class="invalid-feedback" role="alert">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
<button type="submit" class="btn btn-outline-info btn-block"><i class="ft-unlock"></i>
{{ __('Login') }}
</button>
{{ Form::close() }}
</body>
</html>
PagesController
class PagesController extends Controller
{
protected $redirectTo = '/'; // Redirect after successfull login
public function __construct()
{
$this->middleware('auth');
}
public function tableau_bord()
{
return view('pages.tableau_bord');
}
}
Methods using when login in LoginController
class LoginController extends Controller
{
protected $redirectTo = '/';
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->username = $this->findUsername();
}
public function findUsername()
{
$login = request()->input('login');
$fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' :
'nom_utilisateur';
request()->merge([$fieldType => $login]);
return $fieldType;
}
public function login(Request $request)
{
$this->validateLogin($request);
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
protected function validateLogin(Request $request)
{
$request->validate([
$this->username => 'required|string',
'mot_de_passe' => 'required|string',
]);
}
protected function attemptLogin(Request $request)
{
return $this->guard()->attempt(
array($this->username => $request->login, 'password' =>
$request > mot_de_passe)
);
}
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}
protected function authenticated(Request $request, $user)
{
return redirect()->to($this->redirectPath());
}
public function redirectPath()
{
if (method_exists($this, 'redirectTo')) {
return $this->redirectTo();
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/';
}
public function redirectTo()
{
return $this->redirectTo;
}
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
public function username()
{
return $this->username;
}
protected function credentials(Request $request)
{
return $request->only($this->username(), 'mot_de_passe');
}
}
if any one has this problem i solved by rename the table to users and the email/password fields in the DB & login form & loginController & config/auth.php ...
basically back to stage after make:auth command apparently laravel hate change the users table :(
Related
I'm building a page with 2 logins. So every login has its own blade file. The redirect happens in the LoginController.php i replace this protected $redirectTo = '/page1'; with
function redirectTo(){
if(true){
return '/page1';
} else {
return '/page2';
}
}
It works, that means that it doesn't throw an error. But how can I pass an argument to this function and at which place/file this function is being called?
Create a hidden input field in both your forms as
form1:
<input type="hidden" name="page" value="page1">
form2:
<input type="hidden" name="page" value="page2">
Now in LoginController
use \Illuminate\Http\Request; // add this line
protected function authenticated(Request $request, $user)
{
if (Auth::attempt(['email' => request('email'), 'password' => request('password'), 'verified' => 1])) {
// Authentication passed...
if($request->input("page") == "page1") {
return redirect()->intended('page1');
} else {
return redirect()->intended('page2');
}
}
}
Create a function called authenticated() insdide your LoginController.php, then create your own implementation base on what you need to do.
Example:
protected function authenticated(Request $request, $user)
{
if ($user->role == 'Administrator') {
return redirect('/admin-page');
} else if($user->role == 'Guest') {
return redirect('/guest-page');
}
abort(401);
}
I am working on a messaging functionality on my website between two users and I have managed to make the messaging system work quite alright. But I have a little issue which I can't find a solution to it. I want to be able to show, A list of all message received from other users when the user clicks on this route /conversations. But right now what it does is that it display a list of all users in the users table when I click on the route /conversations which I don't want.
Here are my routes in web
Route::get('/conversations', 'ConversationsController#index')->name('conversations');
Route::get('/conversations/{user}', 'ConversationsController#show')->name('conversations.show');
Route::post('/conversations/{user}', 'ConversationsController#store');
Here is my list of conversations route for index
<div class="contact-edit" id="ci">
<h3>MEssages</h3>
#include('conversations.users', ['users'=>$users, 'unread'=>$unread])
</div>
Here is the conversation.users
<div class="col-md-3">
<div class="list-group">
#foreach($users as $user)
<a class = "list-group-item d-flex justify-content-between align-items-center" href="{{route('conversations.show', $user->id)}}">
{{ $user->name }}
#if(isset($unread[$user->id]))
<span class="badge-pill badge-primary">{{$unread[$user->id]}}</span>
#endif
</a>
#endforeach
</div>
Here is my route opening the conversations tab
Ecrire un message
Here is my conversation controller
class ConversationsController extends Controller
{
private $r;
private $auth;
public function __construct(ConversationRepository $conversationRepository, AuthManager $auth)
{
$this->r = $conversationRepository;
$this->middleware('auth');
$this->auth = $auth;
}
public function index (User $user){
$me = Auth::user();
//dd(Auth::user());
return view('conversations/index', [
'users'=>$this->r->getConversations(Auth::user()->id),
'unread' => $this->r->unreadCount(Auth::user()->id)
]);
}
public function show (User $user){
$me = Auth::user();
$messages = $this->r->getMessagesFor($me->id, $user->id)->paginate(5);
$unread = $this->r->unreadCount($me->id);
if (isset($unread[$user->id])) {
$this->r->readAllFrom($user->id, $me->id);
unset($unread[$user->id]);
}
return view('conversations/show', [
'users'=>$this->r->getConversations($me->id),
'user'=>$user,
'messages'=>$messages,
'unread' => $unread
]);
}
public function store (User $user, StoreMessageRequest $request){
$message = $this->r->createMessage(
$request->get('content'),
Auth::user()->id,
$user->id
);
$user->notify(new MessageReceived($message));
return redirect(route('conversations.show', ['id'=>$user->id]));
}
}
And here is my conversation repository
class ConversationRepository
{
private $user;
private $message;
public function __construct(User $user, Message $message)
{
$this->user = $user;
$this->message = $message;
}
public function getConversations(int $userId)
{
$conversations = $this->user->newQuery()
->select('name','surname','photo','id')
->where('id', '!=', $userId)
->whereType('jobber')
->get();
return $conversations;
}
public function createMessage(string $content, int $from, int $to)
{
return $this->message->newQuery()->create([
'content'=>$content,
'from_id'=>$from,
'to_id'=>$to,
'created_at'=>\Carbon\Carbon::now()
]);
}
public function getMessagesFor(int $from, int $to) : Builder
{
return $this->message->newQuery()
->whereRaw("((from_id = $from AND to_id = $to )OR(from_id = $to AND to_id = $from))")
->orderBy('created_at', 'DESC')
->with([
'from'=> function ($query){ return $query->select('name', 'id');}
]);
}
//Recupere le nombre de message non lu pour chaque conversation
public function unreadCount (int $userId)
{
return $this->message->newQuery()
->where('to_id', $userId)
->groupBy('from_id')
->selectRaw('from_id, COUNT(id) as count')
->whereRaw('read_at IS NULL')
->get()
->pluck('count', 'from_id');
}
THis is my user model
public function messages()
{
return $this->hasMany('App\Message', 'from_id', 'to_id', 'content');
}
This is message model
public function user()
{
return $this->belongsTo('App\User');
}
Any help will be welcome
I'm not sure I am understanding what you want to do but here is a possible solution assuming you want to get all messages that are to you.
In your repository:
$this->message->where('to_id',Auth::user()->id)->get();
Here is my MessageController.php file
class MessageController extends Controller
{
protected $authUser;
public function __construct()
{
$this->middleware('auth');
Talk::setAuthUserId(Auth::user()->id);
View::composer('partials.peoplelist', function($view) {
$threads = Talk::threads();
$view->with(compact('threads'));
});
}
public function chatHistory($id)
{
$conversations = Talk::getMessagesByUserId($id);
$user = '';
$messages = [];
if(!$conversations) {
$user = User::find($id);
} else {
$user = $conversations->withUser;
$messages = $conversations->messages;
}
return view('messages.conversations', compact('messages', 'user'));
}
public function ajaxSendMessage(Request $request)
{
if ($request->ajax()) {
$rules = [
'message-data'=>'required',
'_id'=>'required'
];
$this->validate($request, $rules);
$body = $request->input('message-data');
$userId = $request->input('_id');
if ($message = Talk::sendMessageByUserId($userId, $body)) {
$html = view('ajax.newMessageHtml', compact('message'))->render();
return view('messages.conversations', compact('messages', 'user'));
}
}
}
public function ajaxDeleteMessage(Request $request, $id)
{
if ($request->ajax()) {
if(Talk::deleteMessage($id)) {
return response()->json(['status'=>'success'], 200);
}
return response()->json(['status'=>'errors', 'msg'=>'something went wrong'], 401);
}
}
i am trying to send a message from this form
<form action="{{url('/message_send')}}" method="post" id="talkSendMessage">
<textarea name="message-data" id="message-data" placeholder ="Type your message" rows="3"></textarea>
<input type="hidden" name="_id" value="{{#request()->route('id')}}">
<button type="submit">Send</button>
</form>
but it doesnt work, an error saying NotFoundHttpException in RouteCollection.php line 161: and here is my routes.php file
Route::get('message/{id}', 'MessageController#chatHistory')->name('message.read');
Route::group(['prefix'=>'ajax', 'as'=>'ajax::'], function() {
Route::post('message_send', 'MessageController#ajaxSendMessage')->name('message.new');
Route::delete('message/delete/{id}', 'MessageController#ajaxDeleteMessage')->name('message.delete');
});
I dont understand where the error is coming from??
You have missed the prefix you defined in your route group.
Route::group(['prefix'=>'ajax', 'as'=>'ajax::'], function() {
You have to add the prefix as well to the form's action,
<form action="{{url('/ajax/message_send')}}" method="post" id="talkSendMessage">
When you validate your data using a request service how do you return the the errors in json format like e.g.
return response->json(array("errors' => true, 'errors' => $errors));
Request Service:
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Auth;
class MyRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
protected $action;
public function authorize()
{
if(Auth::check()) {
return true;
}
}
public function validate() {
return parent::validate();
}
public function all()
{
}
public function messages()
{
}
public function rules()
{
}
}
Controller:
public function store(MyRequest $request) {
$mymodel = new MyModel();
$mymodel->title = 'test';
$model->save();
}
You don't have to do it manually, it will automatically sends an errors response, which could be use like:
#if ($errors->has())
<div class="alert alert-danger">
#foreach ($errors->all() as $error)
{{ $error }}<br>
#endforeach
</div>
#endif
OR
#if ($errors->has('name')) <p class="help-block">{{ $errors->first('name') }}</p> #endif
OR
Skip Request and do Validator::make() and in the end do:
return response($validatorObject->messages(), 500);
I'm having trouble logging in. Even when there are no validation errors to be found, it goes to the else statement block in my postIndex method and brings me back to the login page. Any idea on what the problem is and what do i need to change to fix it?
routes.php
<?php
Route::get('/', 'HomeController#getGuestIndex');
Route::controller('login', 'LoginController');
?>
HomeController.php
<?php
class HomeController extends BaseController {
public function getGuestIndex()
{
return View::make('guests.index');
}
public function getAdminIndex()
{
return View::make('admin.index');
}
}
?>
LoginController.php
<?php
class LoginController extends BaseController {
public function getIndex()
{
// Check if we are already logged in.
if (Auth::check()) {
return Redirect::action('HomeController#getAdminIndex')
->with('message', 'You are already logged in');
}
return View::make('guests.login')
->with('title', 'Login');
}
public function postIndex()
{
// Get all the inputs
$user = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
$validation = User::validate($user);
if ($validation->passes()) {
// Try to log the user in.
if (Auth::attempt($user)) {
return Redirect::action('HomeController#getAdminIndex')
->with('message', 'You have logged in successfully');
}
return Redirect::to('login')
->withErrors($validation)
->withInput(Input::except('password'));
} else {
// Something went wrong.
return Redirect::back()
->withErrors($validation)
->withInput(Input::except('password'));
}
}
}
?>
BaseModel.php
<?php
class BaseModel extends Eloquent {
public static function validate($inputs)
{
return Validator::make($inputs, static::$rules);
}
}
?>
User.php
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends BaseModel implements UserInterface, RemindableInterface {
protected $table = 'users';
protected $hidden = array('password');
protected static $rules = array(
'username' => 'required|alpha_dash|min:4',
'email' => 'required|email',
'password' => 'required|alpha_num|min:8|confirmed',
'password_confirmation' => 'required|alpha_num|min:8'
);
public function getAuthIdentifier()
{
return $this->getKey();
}
public function getAuthPassword()
{
return $this->password;
}
public function getReminderEmail()
{
return $this->email;
}
}
?>
login.blade.php
#extends('layouts.master')
#section('content')
<h2>Login into your account</h2>
{{ Form::open(array('url' => 'login')) }}
<p>
{{ Form::label('username', 'Username') }}
{{ Form::text('username', Input::old('username')) }}
</p>
<p>
{{ Form::label('password', 'Password') }}
{{ Form::password('password') }}
</p>
<p>
{{ Form::submit('Login') }}
</p>
{{ Form::close() }}
<p>{{ $errors->first('username') }}</p>
<p>{{ $errors->first('password') }}</p>
#stop
Based on your question and example script the validation is failing.
The problem is likely with the model based validation implementation. You are validating login with registration rules.
One set of validation rules does not fit all situations.
If you add the following lines to your login.blade.php I think you will see additional errors:
<p>{{ $errors->first('email') }}</p>
<p>{{ $errors->first('password_confirmation') }}</p>
To fix it, you will need to either change the validation rules on your model, or change the validation implementation. These two excellent tutorials show a couple approaches:
https://tutsplus.com/lesson/validation-services/
https://tutsplus.com/lesson/validating-with-models-and-event-listeners/