Laravel 302 redirect issue - laravel

I am trying to get info from action, but when click, just page refresh and in console I get code 302 and stay on current page.
I read a lot of similar topics here but found nothing.
I am trying to execute http://laravel2.lo/getUserChannels?user_id=2
Laravel 5.7.16
route:
Auth::routes();
Route::group(['middleware' => ['auth']], function () {
Route::view('createUser', 'createuser');
Route::view('createChannel', 'createchannel');
Route::view('joinChannel', 'joinchannel');
Route::get('profile', 'UserController#profile');
Route::get('users', 'UserController#users');
Route::get('getChannelUsers', 'UserController#getChannelUsers');
Route::get('getUserChannels', 'ChannelController#getUserChannels');
});
ChannelController:
class ChannelController extends Controller
{
public function getUserChannels(Request $request)
{
$this->validate($request, [
'user_id' => 'required|integer',
]);
/** #var User $user */
$user = User::find($request->user_id);
return view('singleuser', ['channels' => $user->channels, 'username' => $user->name]);
}
}
In the log file no errors.
Thanks for any help and advise.

I don't think you'll receive query params as anything other than strings, so your integer validation fails.
To improve your error handling you could customize your App\Exceptions\Handler, catch your ValidationException errors with something like get_class() or instanceOf and do some neat stuff there
And of course you could not use query params at all by using Route::get('getUserChannels/{id}', 'controller#show'); and access it /getUserChannels/2 - then you could probably validate it as an integer
You could go with
Route::get('getUserChannels/{id}', ...
public function getUserChannels($id)
{
$user = User::findOrFail($id);
return view('singleuser', [
'channels' => $user->channels,
'username' => $user->name
]);
}
Then it would just throw a 404 if string, not found etc...

class ChannelController extends Controller
{
public function getUserChannels(Request $request)
{
$validator = \Validator::make($request->all(), ['user_id' => 'required|integer']);
if($validator->fails())
{
$error = $validator->errors()->first();
dd($error);
}
/** #var User $user */
$user = User::find($request->user_id);
return view('singleuser', ['channels' => $user->channels, 'username' => $user->name]);
}
}

Related

Return to a View from Controller after an Api call - Laravel 8

So guys,
I have an app that needs to login.
After login and getting the API and token, it has to redirect to a dashboard, but unfortunately, I can't make it to a dashboard view.
I try to find answers on the forum but can't find one that suits my code.
Here is my api.php
Route::post('/login', App\Http\Controllers\api\LoginController::class)->name('login');
my web.php
Route::get('/dashboard', [Controller::class, 'dashboard']);
my LoginController
class LoginController extends Controller
{
/**
* Handle the incoming request.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function __invoke(Request $request)
{
//set validation
$validator = Validator::make($request->all(), [
'email' => 'required',
'password' => 'required'
]);
//if validation fails
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
//get credentials from request
$credentials = $request->only('email', 'password');
//if auth failed
if(!$token = auth()->guard('api')->attempt($credentials)) {
return response()->json([
'success' => false,
'message' => 'Email atau Password Anda salah'
], 401);
}
//if auth success
return response()->json([
'success' => true,
'user' => auth()->guard('api')->user(),
'token' => $token
], 200);
}
my AuthController :
class AuthController extends Controller
{
public function login(Request $request){
$email = $request->input("email");
$password = $request->input("password");
$request = Request::create('http://localhost:8000/api/login', 'POST',[
'name'=>$email,
'password'=>$password,
]);
$response = json_decode(Route::dispatch($request)->getContent());
// echo($response->success);
if($response->success == 1 || true){
return redirect()->route('dashboard',["response"=>$response]);
}else{
return redirect()->back();
}
}
}
Controller.php where dashboard route is defined:
public function dashboard()
{
return view('dashboard', [
"title" => "Dashboard",
]);
}
if I'm using this code, the error I get is:
Route [dashboard] not defined.
but if I'm not using return redirect and use return view instead. I can go to my dashboard, but the URL is localhost:8000\auth\login which is not what I want.
is there any suggestion so I can get my view on Dashboard?
Thank you very much.

Laravel 9: Auth::user() / auth()->user() null after successfull login

I made a manual login system in a Laravel 9 API that it's works correctly, but when I try to use Auth::user() in another controller, I get it as null, but when I return the auth->user() to the Vue SPA, I get it correctly. Is there a way to it is setting Auth::user() null after a successfull login? Here's are my api.php (api routes):
route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
route::controller(UserController::class)->group(function () {
route::post('/register', 'register');
route::post('/login', 'login');
route::get('/logout', 'logout');
});
route::resource('book', BookController::class);
route::get('/my_books/{user_id}', [BookController::class, 'myBooks']);
As you can see in the image above, I can get the authenticated user after try login it, here's my login method:
public function login(Request $request)
{
$validate = $request->validate([
'email' => 'required|email',
'password' => 'required'
]);
if ($validate) {
$credentials = $request->only('email', 'password');
return Auth::attempt($credentials)
? Auth::user() :
response()->json('No se ha podido iniciar sesiĆ³n', 500);
}
return response()->json($validate->errors, 422);
}
But when I'm going to store a new book, I get the following error:
Here's the error, when I try to use the auth()->user() method to get the logged in user's id:
public function store(Request $request)
{
$validate = $request->validate([
'title' => 'required',
'genre' => 'required'
]);
if ($validate) {
$book = Book::create([
'title' => $request->title,
'author' => $request->author,
'genre' => $request->genre,
'subgenre' => $request->subgenre,
'opinion' => $request->opinion,
]);
$user = User::find(auth()->user()->id);
if ($request->cover) {
$this->uploadImage($request, 'cover', $book);
}
$user->books()->save($book);
return new BooksResource($book);
}
I don't know why it's happening, and I'd like any idea or possible solution. Thanks in advance:
From laravel 9 documentation
// Get the currently authenticated user's ID...
$id = Auth::id();
Also, you should describe your
route::get('/my_books/{user_id}', [BookController::class, 'myBooks']);
route before resource route.
I guess, you dont need this assign $user = User::find(auth()->user()->id); just use auth()->user
To get the Authenticated user, put the book route inside the auth:sanctum middleware.

How to check if the user is admin in Laravel?

As a checklogin function in my Controller I have
public function checkLogin(Request $request)
{
//if the validation rule isn't passed it will be redirected to login form with validation error
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:3'
]);
$user_data = array(
'email' => $request->get('email'),
'password' => $request->get('password'),
);
if (Auth::attempt($user_data)) {
return redirect('/successlogin');
//user will be redirected to successlogin method
} else {
return back()->with('error', 'Wrong Login Details');
//by using back() he will be redirected to the previous location
}
}
And I added a $table->boolean('is_admin')->default(0); column to my model
Also I've tried to make a middleware. Something like
IsAdmin.php
public function handle($request, Closure $next)
{
if (Auth::user()) {
if (Auth::user()->is_admin) {
return $next($request);
}
return Redirect::to('successlogin');
}
}
But it throws me an error
"Call to a member function send() on null"
Thanks a lot in advance!

Problems creating users in laravel

I am creating the traditional register of users with Laravel and I have a problem to send specific value.
public function postUserRegister(){
$input = Input::all();
$rules = array(
'name' => 'required',
);
$v = Validator::make($input, $rules);
if($v->passes() ) {
$user = User::create(Input::all());
} else {
Session::flash('msg', 'The information is wrong');
return Redirect::back();
}
}
This code works correctly , but I need to send always the same value into table users and this column doesn't appear in the form. How can I send the value of the table if the value doesn't appear?
You can just supply the value manually. There are several ways to do this, here is one:
$user = new User(Input::all());
$user->yourcolumn = $yourdata;
$user->save();
You can use input merge to add extra fields.
Input::merge(array('val_key' => $val_name));
$input = Input::all();
Firstly, I think it would be ideal to clean a bit the method, something like that:
public function postUserRegister(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required'
]);
if ($v->fails()) {
Session::flash('msg', 'The information is wrong');
}
User::create($request->all());
return Redirect::back();
}
And now you can simply assign a data to a specific column by using:
$request->merge(['column_name' => 'data']);
The data can be null, or variable etc. And now the whole code would look something like:
public function postUserRegister(Request $request)
{
$request->merge(['column_name' => 'data']);
$validator = Validator::make($request->all(), [
'name' => 'required'
]);
if ($validator->fails()) {
Session::flash('msg', 'The information is wrong');
}
User::create($request->all());
return Redirect::back();
}
You can add whatever data you want directly into the create method:
public function postUserRegister()
{
$input = request()->all();
if (validator($input, ['name' => 'required'])->fails()) {
return back()->with('msg', 'The information is wrong');
}
$user = User::create($input + ['custom' => 'data']);
//
}
P.S. Merging that data into the request itself is a bad idea.
You can do this in the User model by adding the boot() method.
class User extends Model
{
public static function boot()
{
parent::boot();
static::creating(function ($user) {
$user->newColumn = 'some-value';
});
}
...
}
Reference: https://laravel.com/docs/5.2/eloquent#events

Laravel 5 Multiple form validation rules

So i have three forms on one page. One is to change user's picture, another one is to update personal informations, and the last form is to set a new password.
My issue here is that i'm getting validation errors on the password and password confirmation fields even though i'm trying to update some information (second form).
I have created two requests:
UserEditRequest:
class UserEditRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'firstname' => 'required',
'lastname' => 'required'
];
}
}
UserUpdatePasswordRequest:
class UserUpdatePasswordRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'password' => 'required|confirmed|min:6',
'password_confirmation' => 'required|min:6',
];
}
}
within UserController updatePassword:
public function updatePassword(UserUpdatePasswordRequest $request, $id)
{
$user = User::findOrFail($id);
$user->password = bcrypt($request->get('password'));
$user->save();
return redirect()->route('user.edit',$id)->with('success','Password changed.');
}
postEdit where I handle the personal details and avatar changes:
public function postEdit(UserEditRequest $request, $id)
{
dd($request->all());
$user = User::findOrFail($id);
if($request->get('avatar'))
{
$destinationPath = public_path() . '/avatars/' . $user->id . '/';
$fileName = $user->id . '.' . $request->file('avatar')->getClientOriginalExtension();
$request->file('avatar')->move($destinationPath, $fileName);
$user->avatar = 'avatars/' . $user->id . '/' . $fileName;
$user->save();
return redirect()->route('user.edit',$id)->with('success','User avatar modified.');
}
$user->fill($request->input())->save();
return redirect()->route('user.edit',$id)->with('success','User details modified.');
}
quicky my routes:
Route::group(['prefix' => 'user', 'as' => 'user.'], function () {
Route::get('profile/{userid}', ['as' => 'edit', 'uses' => 'UserController#getEdit']);
Route::post('profile/{userid}', ['as' => 'edit', 'uses' => 'UserController#postEdit']);
Route::post('profile/{userid}', ['as' => 'updatepassword', 'uses' => 'UserController#updatePassword']);
});
});
Try to differentiate your routes for the postEdit and the updatePassword controller actions
Route::post('profile/{userid}', ['as'=>'edit', 'uses'=>'UserController#postEdit']);
Route::post('profile/password/{userid}', ['as'=>updatepassword', 'uses'=>'UserController#updatePassword']);
Using the same route for two different controller actions won't work. What I mean is how do you expect the router to determine which controller action to invoke when the form action='/profile/id' method='post' ? Hence you need to differentiate the routes.
Hope you got it.

Resources