Laravel login redirect doesn't work - laravel

I have made the login/tregistration form. Registration works well but login redirect doesn't work. I have the following function in my controller:
public function doLogin() {
$credentials = [
'email' => Input::get('email'),
'password' => Input::get('password')
];
if (Auth::attempt($credentials)) {
return Redirect::to('/');
} else {
dd('error');
}
}
and the routes.php
Route::resource('car', 'CarController');
Route::get('users', 'UserController#index');
Route::post('users/register', array('uses' => 'UserController#store'));
Route::post('users/signin', array('uses' => 'UserController#doLogin'));
Route::get('users/logout', array('uses' => 'UserController#doLogout'));
Route::get('/', 'CarController#index');
CarController
public function index() {
$cars = DB::select('select * from cars');
$result = DB::select('select c.*, i.sgs, i.tpl, i.kasko, i.inter_permis from cars as c left join insur_docs as i on i.car_id = c.id');
$date = Carbon::now();
$limit_date = Carbon::now()->addMonths(1);
return View::make('pages.index', array(
'cars' => $cars,
'result' => $result,
'date' => $date,
'limit_date' => $limit_date,
));
}
The problem is that it doesn't redirects to index page just refresh the page. If not correct credentials it shows "error" else if correct credentials it just refresh page and doesn't redirects. I f I replace redirect with success message it shows it. I have the same code localy and login with redirect is ok, but in google app engine (my project online) doesn't redirect.

The example you have used wouldn't actually redirect the user for two reasons.
The use of Redirect::route() excepts the parameter passed to be the name of a route, eg one defined like so
Route::get('/', ['as' => 'home', 'uses' => 'YourController#yourMethod']);
To redirect here you would use Redirect::route('home').
You aren't actually returning the redirect. Any response for a route, whether it be within a controller method or a closure, must be returned using the return keyword.
So to correct your code, it'd be like this:
public function doLogin() {
$credentials = [
'email' => Input::get('email'),
'password' => Input::get('password')
];
if (Auth::attempt($credentials)) {
return Redirect::to('/');
} else {
dd('error');
}
}
I moved the credentials to an array as it looks tidier and it makes it easier to read when displaying on this site, so you don't have to do that, but it may make things easier for you.

Related

Laravel: Feature Test fails because of added middleware

After a user signs up and verifies their email, they must complete their signup with additional information. This happens at /register/complete-signup
The issue makes absolutely no sense to me.
For whatever reason, when I added my Middleware has-not-completed-signup, the test starts failing because a App\User no longer has the associated App\Account which is happening in the controller via attach()
As soon as I remove my middleware from the route, it works fine.
My middleware is there to prevent a user who has completed the signup already from visiting or POSTing to those routes. I tested in the browser and the redirect works. The controller method is being used in the test and i can dd($account->users) and get the correct response. But if I do $user->accounts, the collection is empty.
Once I remove my middleware, $user->accounts is no longer empty. But I did a dd() inside my middleware and it's not even running (which is correct because the user doesn't have an account).
So why would this make it fail? I'm completely lost.
I tried to include all relevant information below. If there is something else you need, please let me know.
Edit:
In my middleware, I've commented out the functionality. Something about checking an eloquent relationship makes me test fail. I have no idea why.
This makes the test fail:
if (!auth()->user()->accounts->isEmpty()) {
//return redirect(RouteServiceProvider::HOME);
}
If for example I change it to something useless like this, it works:
if (auth()->user()) {
//return redirect(RouteServiceProvider::HOME);
}
I can do $account->users , but $user->accounts returns empty collection on the controller when I use my middleware
Original:
Here are my routes:
// auth scaffolding
Auth::routes(['verify' => true]);
// main app routes
Route::middleware('verified', 'auth')->group(function() {
// User verified and has an App\Account
Route::middleware('completed-signup')->group(function() {
Route::get("/", 'HomeController#index' )->name('home');
Route::get('/paywall', 'BillingController#paywall')->name('paywall');
});
// The user hasn't attached an App\Account to their User
Route::middleware('has-not-completed-signup')->group(function() {
Route::get("/register/complete-signup", 'AccountController#showCompleteSignup' )->name('complete-signup');
Route::post('/register/complete-signup', 'AccountController#storeCompleteSignup')->name('complete-signup.store');
});
});
has-not-completed-signup Middleware:
public function handle($request, Closure $next)
{
if (auth()->user()->hasCompletedAccountSetup()) {
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
App/User method:
Class User extends Authenticatable implements MustVerifyEmail {
...
public function accounts() {
return $this->belongsToMany('App\Account', 'account_role_user')->withPivot('role_id');
}
public function hasCompletedAccountSetup() {
return !$this->accounts->isEmpty();
}
...
AccountController#storeCompletedSignup:
public function storeCompleteSignup(Request $request) {
$validatedData = $request->validate([
'company' => 'required|max:255',
'contact_state' => 'required|max:255',
'contact_country' => 'required|max:255',
'contact_zip' => 'required|max:255',
'contact_city' => 'required|max:255',
'contact_phone' => 'nullable|max:255',
'contact_address_1' => 'required|max:255',
'contact_address_2' => 'nullable|max:255',
'contact_first_name' => 'required',
'contact_last_name' => 'required',
'contact_email' => 'required'
]);
$user = auth()->user();
$account = new Account($validatedData);
$account->contact_first_name = $user->first_name;
$account->contact_last_name = $user->last_name;
$account->contact_email = $user->email;
$account->save();
$account->users()->attach(
$user->id,
['role_id' => Role::where('name', 'owner')->first()->id ]
);
return $request->wantsJson()
? new Response('Signup Completed Successfully', 201)
: redirect()->route('/');
}
My Test:
/**
* #test
*/
public function a_user_can_complete_signup()
{
$user = Factory('App\User')->create();
$this->actingAs($user);
$accountAttributes = factory('App\Account')->raw([
'contact_first_name' => "TEST",
'contact_last_name' => $user->last_name,
'contact_email' => $user->email,
'contact_country' => "USA"
]);
$res = $this->post('/register/complete-signup', $accountAttributes);
$res->assertSessionDoesntHaveErrors();
$this->assertTrue( !$user->accounts->isEmpty() ); // THIS FAILS
$this->assertTrue( $user->accounts->first()->company == $accountAttributes['company']);
$this->assertTrue( $user->accounts->first()->contact_first_name == $user->first_name );
}
The issue wasn't actually with the middleware, but it was because I had to refresh the model after the POST on the test.
$this->assertTrue( !$user->accounts->isEmpty() );
needed to become
$this->assertTrue( !$user->fresh()->accounts->isEmpty() );
which passed the test.
I knew about the fresh and refresh() methods, but the middleware causing the issue didn't make sense to me.

Keep getting "MethodNotAllowedHttpException" when trying to display a page redirected from an external URL

I'm trying to reach to my local page from an external URL, which is from a payment gateway, based on the return URL parameter. However, when I link it back to my page, I keep getting the "MethodNotAllowedHttpException" error. Below are my codes;
Order Controller:
public function kiplestatus(Request $request, $id) {
dd($request);
$showFeedbackForm = true;
$order = \App\Order::where('id', $id)->get();
}
Route:
Route::get('/order/kiplestatus/{id}', [
'uses' => '\App\Http\Controllers\OrderController#kiplestatus',
'as' => 'order.kiplestatus',
'middleware' => ['auth','verify.mobile.no','agent'],
]);
Am I doing anything wrong here?

LARAVEL & VUE: How can I get the API_TOKEN of the logged in user with an API request?

I have a SPA using VUE and LARAVEL 5.8
I have setup an API_TOKEN associated to the logged in user. Everything works fine right after the login. I get the API_TOKEN, I save it into a var and I send it together with the Axios request. In Laravel I have a middleware that is taking care of the token and comparing it with the one setup on the logged in user.
the problem though occur when session expires. Because I still can navigate the private pages and make API requests to save and delete content. This is possible I think because I still have the same API_TOKEN saved in the var and the middleware apparently doesn't get that the session is expired.
So I want to obtain the API_TOKEN every time I'm doing an Ajax, request so when the session expires, I won't get the token and therefore, I won't be able to complete the request.
This is my setup.
web.php is where I have the only php route that points to a singlePageController:
Auth::routes();
Route::get('/{any}', 'SinglePageController#index')->where('any', '.*');
Then in the singlePageController I return the view:
class SinglePageController extends Controller
{
public function index() {
return view('app', ['loggedUser' => auth()->user()]);
}
}
Then I have the api.php where I have the API routes. As you can see at the end I have the middleware to make it private. Just to make an example this is the one I use for updating the content:
Route::put('event/update/{slug}', 'EventController#update')->middleware('auth:api');
Then the related controller of that API route:
public function update(Request $request, $slug)
{
$event = Event::where('slug', $slug)->first();
$event->title = $request->input('title');
return new EventResource($event);
}
And in the end this is the Resource I use to define what and how the API data is going to be displayed:
public function toArray($request)
{
// return parent::toArray($request);
return [
'id' => $this->id,
'title' => $this->title,
'slug' => $this->slug,
'curator' => $this->curator,
'featured_image' => $this->featured_image,
'body' => $this->body,
'date' => $this->date
];
}
So this above is the flow I have. Then when I do an axios call to update the content, I'm doing something like:
axios({
method: 'PUT',
url: '/api/event/update/' + this.$route.params.slug + '?api_token=' + this.isLogged.apiToken,
data: dataToSave,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
})
.then((response) => {
this.getNotification('Success: The Event has been saved');
})
.catch((error) => {
this.getNotification('Error: Impossible saving the event');
console.log(error);
})
Do you know how to make it? or if there is a better way to accomplish that?
you and do like, your login method should like this.
public function login(Request $request)
{
if (Auth::attempt(['email' => $request['email'], 'password' => $request['password']])) {
$user = Auth::user();
$success = $user->createToken(config('app.name'))->accessToken;
return response()->json(["token" => $success, 'status' => 200]);
} else {
return response()->json(['message' => "Email or Password do not match"], 401);
}
}

Laravel | How to append parameter to URL when using Redirect::route and Redirect::back()?

My view provides links like http://finance.dev/home/customer/6#tab_1_3 so that user a can directly navigate to a tab in the page using the link.
In my routes I have :
Route::get('/home/customer/{id}',[
'as' => 'home.customer',
'uses' => 'CustomerController#show'
]);
Route::get('/home/customer/{id}/{navigate}/{tab}',[
'as' => 'home.customer.navigate',
'uses' => 'CustomerController#navigate'
]);
I am passing the required variables to route using:
window.location.href = '/home/customer/'+id+'/'+navigate+'/'+tab;
And my controller logic is :
public function navigate($id, $navigate, $tab)
{
$user = customer::find($id);
if($navigate == 'previous')
{
// get previous user id
$go = customer::where('id', '<', $user->id)->max('id');
}
elseif ($navigate == 'next') {
// get next user id
$go = customer::where('id', '>', $user->id)->min('id');
}
else{
return \Redirect::back();
}
return \Redirect::route('home.customer', array('id' => $go));
}
The above code successfully returns a URL like http://finance.dev/home/customer/6
Now I am trying to figure out how to define \Redirect::route and \Redirect::back() to return a URL like http://finance.dev/home/customer/6#tab_1_3
How can I go about this?
$url = URL::route('home.customer', ['id' => $go])."#tab_1_6";
return \Redirect::to($url);
Reference Link

How can I return two times back in Laravel 4.2?

Which classes to use for caching certain token or url? After login, I want the user to redirect two urls back in Laravel 4.2? I have tried already with URlGenerator and Request class in my User authentification function so I could catch my previous url which is GET request for login, while the desired url is before this request.
My login function:
namespace \Users\Repositories;
use View , Input , Redirect , Config;
use Illuminate\Routing\UrlGenerator;
use Users\Repositories\Contracts\AuthRepositoryInterface;
use Illuminate\Support\MessageBag;
use Illuminate\Http\Request;
class AuthRepository implements AuthRepositoryInterface {
private $messageBag;
private $errors;
private $urlGenerator;
private $request;
public function __construct(MessageBag $messageBag, UrlGenerator $urlGenerator, Request $request) {
$this->messageBag = $messageBag;
$this->urlGenerator = $urlGenerator;
$this->request = $request;
}
public function postLogin() {
$remember_me = (Input::get('remember_me') == 1 ? true : false);
try
{
// Login credentials
$credentials = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
);
// Authenticate the user
$user = \Sentry::authenticate($credentials, $remember_me);
// giving example
//if(token or url)
//redirect to 'frontend.fee.registration'
//else
return Redirect::route('profile')->with('success' , trans('users::success.login_success'));
}
My routes:
Route::get( '/login' , array( 'as' => 'login' , 'uses' => 'HomeController#userLogin' ) );
Route::post('/login' , array( 'as' => 'postLogin' , 'uses' => '\Users\Controllers\AuthController#postLogin' ) );
Redirect destination:
Route::get('/fee/{id}/register/' , array( 'as' => 'frontend.fee.registration' , 'uses' => 'FeeController#feeRegistration' ) );
There is no built in solution, but you can use session to save current URLs and then use them to go back 2-3-4 etc pages back.
Look at the answer and the code here: How to return back twice in Laravel?

Resources