Laravel Fortify returns Not Found - laravel

I send a xhr request to /login route. It does login, but the response is an html with text Not Found. I realize that fortify is saying this coz it cant find the logged in view. I have enabled views, 'views' => true in config/Fortify.php. But I want Fortify to return a success response text after successful login. How can I do this?

You can customise your response based on the request type:
public function func(Request $request)
{
if ($request->ajax()) {
return response()->json('AJAX response', 200);
}
return view('my-view');
}

Related

Laravel Inertia (Vue) - Authenticate without Redirect

I'm making a normal Inertia post to a base Laravel login route:
submit() {
this.$inertia.post("/login", {
email: this.emailAddress,
password: this.password,
}, {
preserveState: true,
preserveScroll: true,
});
}
I'm able to catch validation errors as expected, but what I'm trying to avoid is the redirect after a successful user authentication, and instead proceed in the "logged in" state (update header to show user info, etc).
The Laravel AuthenticatesUsers trait contains this contains two key methods that gets called as part of the out-of-the-box login flow
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
and
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if ($response = $this->authenticated($request, $this->guard()->user())) {
return $response;
}
return $request->wantsJson()
? new Response('', 204)
: redirect()->intended($this->redirectPath());
}
I'm struggling to figure out if it's even possible to authenticate a user without redirecting this way.
You need to utilize the javascript frontend, not Inertia::post() . One way to do this is to use Axios:
submit() {
const data = {...this.form.data()};
axios.post('/auth/login', data, {
headers: {
'Content-Type': 'application/json',
},
})
.then(res => {
console.log('login success!', res);
});
Check your form and the way you submit - do you prevent the default behavior of the form submit? It seems like you are sending a POST but the native form behavior is also triggered.
You can also set a $redirectTo in your LoginController, also check RouteServiceProvider there is a public const HOME = '/' which triggered the redirect if nothing else is given.
This are my two cents...
A few days ago I was struggling with passing the result of the script to Vue without redirecting, using Inertia visits instead of Axios.
The solution I adopted was the following:
In vue:
this.$inertia.visit(`URL`, {
method: "post",
data: { //Email and password },
preserveState: false,
preserveScroll: false,
onError: (errors) => { // do what ever is needed if validation fails },
onSuccess: () => { // do what ever is needed if validation succeeds }
});
In Laravel:
// If validation fails:
return redirect()->back()->withErrors([
'login' => 'Validation fail details.'
]);
// If validation succeeds:
return redirect()->back()->with('login', 'Success message!');
This way the page does not redirect and the user can continue exactly wherever he is.
What i'm not sure is if it's possible to pass the user info over the success redirect message. Maybe returning a array like it's done in withErrors. If not possible it's always possible to make an additional request to the server to retrieve the desired information.
Hope it's usefull.

laravel passport giving Unauthenticated error

I am using laravel passport but when I try to hit the post route that gives me user data it's giving me error like
{"message":"Unauthenticated."}
here is my controller method
public function getDetails()
{
$user = Auth::user();
return response()->json(['success' => $user], $this->successStatus);
}
api.php
Route::post('register', 'API\PassportController#register')-
>name('register');
Route::post('login', 'API\PassportController#login')->name('login');
//Route::post('details', 'API\PassportController#getDetails')->middleware('auth:api');
Route::group(['middleware' => 'auth:api'], function(){
Route::get('user', 'API\PassportController#user');
Route::post('details', 'API\PassportController#getDetails');
});
screenshot of postmen
please let me know what inputs you want from my side
Your codes look ok to me, but if I'm not mistaken you added your "Authorization" manually: please try this way from the image below, by clicking on Authorization tab, left next to Headers tab.
And make sure that your token is the one that is returned from the server when you make login request: see the image below.

Redirect user to homepage if he is not authorized to access page its not working properly

If a user creates a conference with id "2" he should be allowed to access "proj.test/conference/manage/2".
But a user that did not create the conference with id "2" should be redirected to the login page if he is not authenticated. If he is authenticated should be redirected to the homepage.
But its not working properly, if the user created the conference with id 2 he can access "proj.test/conference/manage/2" but other user that did not create this conference if accesses "proj.test/conference/manage/2" it appears an error:
This action is unauthorized.
So instead of redirecting the user to the homepage it shows this error. Do you know why is not working?
I have the store method, after storing the conference the user is redirected to the management area to manage that specific conference, for example, to manage the conference with id 2 the user is redirected to "proj.test/conference/manage/2".
Store method:
public function store(Request $request)
{
$this->validate($request, [
'conference_name' => 'required|max:255|string',
...
]);
$conference = Conference::create([
'name' => $request->conference_name,
...
]);
}
Then in the AuthServiceProvider I add:
public function boot(GateContract $gate)
{
$this->registerPolicies();
$gate->define('access-management-area', function($user, $conference)
{
return $user->id == $conference->conference_creator_id;
});
}
And in the manage method I have:
public function manage($id){
$conference = Conference::findOrFail($id);
if($this->authorize('access-management-area', $conference)){
return view('conferences.manage')->with('myconference',$conference);
}
else{
return redirect('/home');
}
}
Do not use $this->authorize as it does not work the same as Gate::allows()/denies().
The authorize method will throw an exception if it fails, it will not return false for the sake of conditional comparison.
From the docs:
If the action is not authorized, the authorize method will throw an Illuminate\Auth\Access\AuthorizationException, which the default Laravel exception handler will convert to an HTTP response with a 403 status code.
So, instead, use Gate::denies for comparisons.
if(Gate::allows('access-management-area', $conference)) {
return view('conferences.manage')->with('myconference',$conference);
} else {
return redirect('/home');
}

Laravel unauthorized page when ajax send request

I'm making web based game. The game need to login first, so I use laravel auth::register and auth::login as usual, and add middleware auth to every pages except login&register page.
Then check the game status using smartupdater if ready or not.
$("section").smartupdater({
url : urlCheckStatus,
data : data,
dataType : 'json',
minTimeout: 2000
}, function(response){
var gameStatus = response.data.status;
if(gameStatus === 'start')
{
gameOn();
}
else if(gameStatus === 'active')
{
pleaseWait();
}
else if(gameStatus === 'stop')
{
backToMenu();
}
});
Register and login function
public function register(Request $request)
{
$name = $request->input('username');
$user = new User;
$user->name = $request->input('username');
$user->email = $name.'#abc.com';
$user->password = bcrypt(Carbon\Carbon::now());
$user->grade = $request->input('grade');
$user->numb = $request->input('numb');
$user->save();
Auth::login($user, true);
return redirect('menu');
}
check game status function
public function checkGameStatus()
{
$game_id = Request::input('game_id');
$data = Game::find($game_id);
return response()->json([
'data' => $data
]);
}
But sometimes I was thrown to login page, because error 401 Unauthorized. Trying to console log like the image above.
Thanks
I see you are using Javascript for authorization with Laravel, as per Laravel documentation for API Authentication with Javascript:
If you are using a different JavaScript framework, you should make
sure it is configured to send the X-CSRF-TOKEN and X-Requested-With
headers with every outgoing request.
Can you ensure X-CSRF-TOKEN and X-Requested-With are always present in your headers.

laravel TokenMismatchExceptions on login

I'm getting this TokenMismatchException with Laravel 4. It happens to me if the browser sits on the login page for a while. For example a lot of times when I come back to work on my project the next day, if my browser has the login page open in a tab, when I try to log in I get the TokenMismatchException. If I'm logging in and out throughout the day while working, I never see it. It's like the token expires or something.
Route.php
// route to show the admin login form
Route::get('login', array('uses' => 'AdminController#showLogin'));
// route to process the admin login form
Route::post('login', array('uses' => 'AdminController#doLogin'));
AdminController.php
public function showLogin()
{
// show the login form
return View::make('admin.login');
}
public function doLogin()
{
// validate the info, create rules for the inputs
$rules = array('username' => 'required','password' => 'required' );
// run the validation rules on the inputs from the form
$validator = Validator::make(Input::all(), $rules);
// if the validator fails, redirect back to the form
if ($validator->fails()) {
return Redirect::to('login')
->withErrors($validator) // send back all errors to the login form
->withInput(Input::except('password')); // send back the input (not the password) so that we can repopulate the form
} else {
// create our user data for the authentication
$userdata = array('my_username'=> Input::get('username'),'password'=> Input::get('password'));
// attempt to do the login
if (Auth::attempt($userdata)) {
return Redirect::intended('dashboard');
} else {
// Authentication not successful, send back to form
return Redirect::to('login')->with('message', 'Your username/password combination was incorrect');
}
}
}
Please, help is needed...
That's normal, session will expire if you get idle for too long. It's a security measure, so you just need to make sure you redirect your user to login when the token expires. Add this to your global.php file or create a exceptions.php file to it:
App::error(function(\Illuminate\Session\TokenMismatchException $exception)
{
return Redirect::route('login')->with('message','Your session has expired. Please try logging in again.');
});

Resources