Adding custom admin panel to laravel with authentication system - laravel

Hi I am trying to add a custom admin panel to my laravel project. I have a login page. After entering valid email and password user can login to dashboard. But Problem is when i enter valid email and password it always stay in the login screen.
Here is my login form
<form class="form-horizontal" action="{{ route('admin.login') }}" method="post">
{!! csrf_field() !!}
<fieldset>
<div class="input-prepend" title="Email">
<span class="add-on"><i class="halflings-icon user"></i></span>
<input class="input-large span10" name="email" required maxlength="100" id="email" type="text" placeholder="type useremail"/>
</div>
<div class="clearfix"></div>
<div class="input-prepend" title="Password">
<span class="add-on"><i class="halflings-icon lock"></i></span>
<input class="input-large span10" name="password" required id="password" type="password" placeholder="type password"/>
</div>
<div class="clearfix"></div>
<label class="remember" for="remember"><input type="checkbox" id="remember" />Remember me</label>
<div class="button-login">
<button type="submit" class="btn btn-primary">Login</button>
</div>
<div class="clearfix"></div>
</fieldset>
</form>
Here is my route
Route::get('/admin/login', [
'as' => 'admin.login',
'uses' => 'AdminController#getLogin'
]);
Route::post('/admin/login', [
'as' => 'admin.login',
'uses' => 'AdminController#postLogin'
]);
Route::group(['middleware' => 'auth'
], function () {
Route::get('/admin', [
'as' => 'dashboard',
'uses' => 'AdminController#index']);
Route::get('/logout', [
'as' => 'logout',
'uses' => 'AdminController#getLogout'
]);
});
Here is my admin Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use Auth;
class AdminController extends Controller
{
public function index()
{
return view('admin.admin_master');
}
public function getLogin()
{
return view('admin.admin_login');
}
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required'
]);
if (Auth::attempt(['email' => $request['email'], 'password' => $request['password']])) {
// Authentication passed...
return redirect()->route('dashboard');
}
return redirect()->back()->with(['fail' => 'Could not Login']);
}
public function getLogout()
{
Auth::logout();
return redirect()->route('admin.login');
}
}
Here is Authenticate.php
use Closure;
use Illuminate\Support\Facades\Auth;
class Authenticate
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest(route('admin.login'))->
withError('You must be logged in !');
}
}
return $next($request);
}
}

Try this middleware
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect('/admin/login'); //edited line
}
}
return $next($request);
}
Try using absolute route instead of using it's alias.

May be it's redirect to login page, because both of your route are same for view getLogin and postLogin. Try to use action() method instead of route() in form action. Ex:
<form class="form-horizontal" action="{{ action('AdminController#postLogin') }}" method="post">
// other codes....
</form>
Tips: If you are using Laravel 5.2 put all of your route inside 'middleware'=>'web'. Ex:
Route::group(['middleware' => ['web']], function () {
// put your routes here.......
}

I had the same problem. I solved it using Auth:login($array). Change your code to
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required'
]);
$data = $request->input();
if(Auth::login($data)){
return redirect('/dashboard');
}
return redirect()->back()->with(['fail' => 'Could not Login']);
}

Related

Update NuxtJs checkbox returning array to string error

I have this in my nuxtjs file
<div class="mt-2">
<span class="block uppercase text-blueGray-600 text-xs font-bold mb-2">Categories</span>
<div v-for="(category, i) in categories" :key="i">
<label class="inline-flex items-center" v-if="category.id != null">
<input type="checkbox" class="form-checkbox" v-model="category.id"
:value="category.id"
>
<span class="ml-2" v-html="category.name"></span>
</label>
<label class="inline-flex items-center" v-else>
<input type="checkbox" class="form-checkbox" v-model="categories.id"
:value="categories.id"
>
<span class="ml-2" v-html="categories.name"></span>
</label>
</div>
</div>
and i have this in my controller
public function store(PostRequest $request)
{
$post = Post::create([
'title' => $request->title,
'body' => $request->body,
'excerpt' => $request->excerpt,
'user_id' => auth()->id(),
]);
$post->categories()->sync($request->catSelected);
return response()->json([
'post' => $post,
'message' => 'Post created successfully.'
], 200);
}
/**
* Display/Edit the specified post.
*
* #param \App\Models\Post $post
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
$post = Post::find($id);
$cat = $post->categories()->get();
return response()->json([
'post' => $post,
'categories' => $cat
]);
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param \App\Models\Post $post
* #return \Illuminate\Http\Response
*/
public function update(PostRequest $request, Post $post)
{
$post->update([
'title' => $request->title,
'body' => $request->body,
'excerpt' => $request->excerpt,
]);
$post->categories()->attach($request->categories);
return response()->json([
'post' => $post,
'message' => 'Post updated successfully.'
], 200);
}
Vuejs script
data:() =>({
errors: [],
title: '',
body: '',
excerpt: '',
categories: [],
}),
async fetch(){
await this.$axios.get('/api/post/'+this.$route.params.id)
.then(response => {
this.title = response.data.post.title
this.body = response.data.post.body
this.excerpt = response.data.post.excerpt
this.categories = response.data.categories
})
},
methods: {
async updatePost(){
this.errors = []
await this.$axios.put('/api/post/update/'+this.$route.params.id , {
title: this.title,
body: this.body,
excerpt: this.excerpt,
categories: this.categories
}).then(()=> this.$router.push('/posts'))
.catch(error => {
if(error.response.status !== 422) throw error
this.errors = Object.values(error.response.data.errors).flat()
})
},
The problem is that anytime i uncheck the selected box and i save it gives "message": "Array to string conversion", but the field is deleted from the database.
Another thing is that i want the category to still be present but unchecked just in case i want to check it again

Livewire validateOnly with validate in the same component

I have a little problem with the data validation with livewire ( laravel ).
I noticed that when I set up the validation in real time ( validateOnly() ), the information entered in the form is validated in real time. At this level everything is fine.
But when I click on the button to submit the form (even though the form contains errors), the form is unfortunately sent to my function defined in the wire:submit.
So my question is : is it possible to revalidate the information in the wire:submit method that receives the data after the form is submitted ? If so, how can I do that?
PS: I tried to set the validate method in my wire:submit function but nothing happens. It blocks the form from being submitted but it doesn't give me an error .
My source code :
<?php
class UserProfile extends Component
{
use WithFileUploads;
public $countries = [];
public $profile = [];
protected function rules() {
if ( !LivewireUpdateProfileRequest::authorize() ) {
return abort(403, "Your are not authorized to make this request !");
}
$rules = LivewireUpdateProfileRequest::rules();
if ( !empty($this->profile['phone']) ) {
$rules['profile.phone'] = [ 'required', 'phone_number:' . $this->profile['phone'] ];
}
return $rules;
}
public function mount()
{
$this->countries = Countries::all();
$this->profile = Auth::user()->toArray();
}
public function updateUserProfile()
{
$validatedData = $this->validate();
dd( $validatedData );
}
public function updated($key, $value)
{
$this->validateOnly($key);
}
public function render()
{
return view('livewire.user-profile');
}
}
Html source :
<form action="" method="POST" wire:submit.prevent="updateUserProfile">
<input name="profile.email" type="email" wire:model="profile.email" />
#error('profile.email') {{ $message }} #enderror
<input name="profile.phone" type="tel" wire:model="profile.phone" />
#error('profile.phone') {{ $message }} #enderror
</form>
Here is LivewireUpdateProfileRequest content :
<?php
namespace App\Http\Requests\Web;
use Illuminate\Foundation\Http\FormRequest;
class LivewireUpdateProfileRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public static function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public static function rules()
{
return [
'profile' => ['required', 'array', 'size:10'],
'profile.firstname' => ['required', 'string'],
'profile.lastname' => ['required', 'string'],
'profile.email' => ['required', 'email'],
'profile.phone' => ['required', 'phone_number:33'],
'profile.gender' => ['required', 'gender'],
'profile.image' => ['sometimes', 'image', 'mimes:png,jpg,jpeg'],
'profile.address' => ['required', 'string'],
'profile.city' => ['required', 'string'],
'profile.country_id' => ['required', 'exists:countries,id'],
'profile.birth_at' => ['required', 'date', 'min_age:18'],
];
}
}
Usually in your saving method you would run validation once more for all fields. The livewire docs share this example:
Livewire Component:
class ContactForm extends Component
{
public $name;
public $email;
protected $rules = [
'name' => 'required|min:6',
'email' => 'required|email',
];
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function saveContact()
{
$validatedData = $this->validate();
Contact::create($validatedData);
}
}
With this HTML:
<form wire:submit.prevent="saveContact">
<input type="text" wire:model="name">
#error('name') <span class="error">{{ $message }}</span> #enderror
<input type="text" wire:model="email">
#error('email') <span class="error">{{ $message }}</span> #enderror
<button type="submit">Save Contact</button>
</form>
This should validate the inputs near-realtime using the updated-method and on submit using the saveContact-method.
If you could share your code, we could debug it easier.
Source: https://laravel-livewire.com/docs/2.x/input-validation#real-time-validation

Error App\Http\Requests\AddUserRequest::fails does not exist

I get this error when I want to insert data into the table and return a message.
Here is my code.
When I entered the form and submitted, an error occurred: Method App\Http\Requests\AddUserRequest::fails does not exist.
Code In Router:
/**************Quản lý user*****************/
Route::get('admin/manage-user', 'UserController#getList')->middleware('admin');
Route::get('admin/manage-user/add', 'UserController#indexAdd')->middleware('admin');
Route::post('admin/manage-user/add', 'UserController#getAdd')->middleware('admin');
Code In UserController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use App\Http\Requests\AddUserRequest;
class UserController extends Controller
{
//
public function getList()
{
$data = User::paginate(10);
return view('admin.manage-user',['data' => $data]);
}
public function indexAdd()
{
return view('admin.add-user');
}
public function getAdd(AddUserRequest $request)
{
if($request->fails())
{
return redirect('admin.add-user')
-> withInput()
-> withErrors($request);
}else
{
User::create([
'name' => $request->username,
'email' => $request->email,
'password' => Hash::make($request->pass1),
'level' => 0,
]);
return redirect('admin.add-user')->with('success',"Done!!");
}
}
}
Code In view:
#extends('layouts.admin')
#section('title','Add User')
#section('content')
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Add User</h3>
</div>
<!-- /.box-header -->
<!-- form start -->
<form role="form" action="{{url('admin/manage-user/add')}}" method="post">
<div class="box-body">
#csrf
<div class="form-group">
#if (session('success'))
<div class="alert alert-success">
<p>{{ session('success') }}</p>
</div>
#endif
#if ($errors->any())
<div class="alert alert-danger">
<b>Lỗi!! Bạn vui vòng kiểm tra lại:</b>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
</div>
In AddUserRequest:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
class AddUserRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'username' => 'required|max:200',
'email' => 'required|email|unique:users',
'pass1' => 'required|min:6',
'pass2' => 'same:pass1',
];
}
}
Thank you for your help!
you don't need to put that check, because data is already validated through your request
public function getAdd(AddUserRequest $request)
{
User::create([
'name' => $request->username,
'email' => $request->email,
'password' => Hash::make($request->pass1),
'level' => 0,
]);
return redirect('admin.add-user')->with('success',"Done!!");
}
AddUserRequest is a FormRequest it doesn't have fails method. For FormRequest you don't need to check fails, it automatically validate your request data using rules provided in that class and throw validation error, for details check here.
For FormRequest validation you use it like this
public function getAdd(AddUserRequest $request)
{
//all code here executed after validation
User::create([
'name' => $request->username,
'email' => $request->email,
'password' => Hash::make($request->pass1),
'level' => 0,
]);
return redirect('admin.add-user')->with('success',"Done!!");
}
If you need to check validation in you controller then use manual validation like this.
public function getAdd(Request $request)
{
$validator = Validator::make($request->all(), [
'username' => 'required|max:200',
'email' => 'required|email|unique:users',
'pass1' => 'required|min:6',
'pass2' => 'same:pass1',
]);
if($validator->fails())
{
return redirect('admin.add-user')
-> withInput()
-> withErrors($request);
}else
{
User::create([
'name' => $request->username,
'email' => $request->email,
'password' => Hash::make($request->pass1),
'level' => 0,
]);
return redirect('admin.add-user')->with('success',"Done!!");
}
}

Laravel: Why are validation messages not show?

I use Laravel 5.4 on hosting. My validation method is working, but it doesn't show messages. I do all the needed operations for displaying errors but it doesn't work.
#if($errors->has('recipient'))
<div class="form-group">
<label class="col-lg-2 control-label"></label>
<div class="col-lg-10">
<div class="alert alert-danger">
<ul>
#foreach ($errors->get('recipient') as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
</div>
</div>
#endif
I use {{ csrf_field() }} tokens. Validation rules work if wrong user types are used, but messages are not displayed.
My send method:
public function send(Request $request)
{
$this->validator($request->all())->validate();
$this->create($request->all());
return redirect($this->redirectToAfterSendMessage);
}
My validator code:
protected function validator(array $data)
{
return Validator::make($data, [
"$this->recipient" => [
'sometimes',
'required',
'email',
'exists:users,email',
Rule::notIn([auth()->user()->email])
],
"$this->subject" => 'sometimes|required|min:10',
"$this->message" => 'sometimes|required|min:50',
], $this->validator_messages());
}
My routes:
Route::get('/compose', 'InboxController#compose') ->name('compose');
Route::post('/compose', 'InboxController#send');
Result of dump($errors):
ViewErrorBag {#244 ▼
#bags: []
}
EDITED
To fix your current problem, change $errors->get('recipient') to $errors->all().
It should look like this:
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
--
This isn't a direct solution for your question. However an even better approach (imo) than yours are custom requests. You can quickly generate custom requests by using the following command:
php artisan make:request CustomRequest
After that you can change type from Request to CustomRequest
public function send(CustomRequest $request)
{
$this->create($request->all());
return redirect($this->redirectToAfterSendMessage);
}
And in CustomRequest.php your extract your validation logic like so:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CustomRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required',
'email' => 'required',
'message' => 'required',
];
}
public function messages()
{
return [
'name.required' => 'Name is required.',
'email.required' => 'Email is required.',
'message.required' => 'Message is required.',
];
}
}
Hope this helps.
You need to change:
"$this->recipient"
"$this->subject"
"$this->message"
To:
'recipient'
'subject'
'message'

Payment preference, Mercadopago's SDK & Laravel 5.5

I'm having a problem while integrating MercadoPago's SDK and Laravel 5.5
Error message:
MercadoPagoException (400)
Wrong number of parameters
Screen:
error screen
Payment Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Models\Cart;
use Exception;
use MP;
class PaymentController extends Controller
{
/**
* Display a listing of the resource.
*
* #return Response
*/
public function process(Request $request)
{
$mp = new MP (env('MP_CLIENT_ID'), env('MP_CLIENT_SECRET'));
$user = auth()->user();
$prefix = 'VSHOPREF-';
$external_reference = $prefix . $request->ctoken;
$token = $request->ctoken;
$preferenceData = [
'external_reference' => $external_reference,
'payer' => [
'name' => $user->name,
'email' => $user->email
],
'back_urls' => [
'success' => env('APP_URL').'/gracias',
'pending' => env('APP_URL').'/gracias',
'failure' => env('APP_URL').'/error'
],
'notification_url' => env('MP_NOTIFICATION_URL'),
'auto_return' => 'all'
];
$entries = Cart::where('session_id', '=', $token)->get();
foreach ($entries as $e):
$preferenceData['items'][] = [
'title' => $e->product_name,
'category_id' => 'zapato',
'quantity' => $e->qty,
'currency_id' => 'VEF',
'unit_price' => $e->price,
];
endforeach;
//dd($preferenceData);
$preference = $mp->create_preference($preferenceData);
dd($preference);
//return init point to be redirected
//return $preference['response']['init_point'];
}
}
Form I'm using to send the payment information
<form class="form-horizontal" action="{!! route('payment.process') !!}" method="post">
{{ csrf_field() }}
<input type="hidden" name="ctoken" id="ctoken" value="{!! $cart_token !!}">
<input type="submit" name="pagar" value="Pagar" class="btn btn-success btn-block btn-sm">
</form>
Btw, I'm sorry for my bad english. I hope you can help me with this issue.
EDIT 1
Thanks to Alexey Mezenin
Well, i wrote "MP_CIENT_SECRET" instead of "MP_CLIENT_SECRET" on my .env file.
NEW ERROR
MercadoPagoException (400)
currency_id invalid

Resources