Laravel 5.2 Authentication Redirect with Parameters - laravel

Since, I was not able to find any question like this in SO, I am writing this post hoping this is not a duplicate...
I have a page developed using KnockoutJs which I am using to protect via Laravel Authentication. Basically, I am using Laravel only for the purpose of login/registration and once the user logs/signs in, he is redirected to the KnockoutJS page.
Now lets just say I have a URL,
http://example.com/mypage#q=some+parameters&p=somethingsomething
If I share that URL with one of my friends, it obviously redirects my friend to the Login Page. Now, the login page URL (where he is redirected to) is
http://example.com/login#q=some+parameters&p=somethingsomething
But once he logs in, he is being redirected to
http://example.com/mypage#
Which obviously is not right, because I need the parameters to be there...
My Routes page is as follows,
Route::group(['middleware' => 'web'], function() {
Route::auth();
Route::get('/', 'MainController#index')->name('home.index');
});
Route::group(['middleware' => ['web','auth']], function () {
Route::get('/mypage', 'MyController#index')->name('mypage.index');
});
And my AuthController has the redirectTo Url set
protected $redirectTo = '/mypage';
What change should I do (in AuthController, or in Routes? Or in a MiddleWare) to redirect the user to
http://example.com/mypage#q=some+parameters&p=somethingsomething
after login?

You can use the intended method in Laravel.
eg:
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
This will redirect the user to the intended URL to the login page or if there is no intended URL, then to dashboard.
https://laravel.com/docs/5.2/authentication#authenticating-users

Since Laravel's Redirect::intended did not work for me, I am posting the answer to this question myself...
User Jquery/Javscript to create cookies after redirection like this :
(function(){
'use strict';
var intended = window.location.hash;
(intended.length > 0) ? jQuery.cookie('intended', '/app' + intended) : jQuery.cookie('intended', '/app');
})();
and make these changes into Laravel 5.2's default AuthController
//Replace the default constructor with this
public function __construct(Request $request) {
if(isset($_COOKIE['intended'])) {
$this->setRedirect($request);
}
}
//Copy paste it anywhere in your AuthController Class
protected function setRedirect($request) {
$intended = (url($_COOKIE['intended']));
$url['intended'] = $intended;
$request->session()->put('url', $url);
}
Hope this helps someone....
Thanks, :)

Related

Change LogIn route

I am working in Laravel auth application and when my user is log out I want to redirect it to custom static page and from there I want to redirect to login page again by clicking button on that page.
For example when user is trying to access some particular route, and he is unauthorized then I want to redirect with satatic.blade.php and from there I want to redirect it to log in page, How can I make it happen?
As you didn't mention which Laravel version you are using and which scaffolding you are using, I am assuming you are using Laravel 5.5/6 with LaravelUI/default auth scaffolding.
You should have App\\Http\\Controllers\\Auth namespace where you kept all auth related controller.
You should have one LoginController.php which contains all default login behavior inside AuthenticatesUsers trait. We should override the login method inside our controller.
Copy this code to your LoginController class to do so.
public function login(Request $request)
{
$this->validateLogin($request);
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
// Here is our custom logic check occurs before login
if ($this->userIsnotAuthorized()) { // All your logic checks are inside 'userIsnotAuthorized()' method. Use any function or static check here
return redirect()->to('/static/page'); // Also can use route name / url
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
EDIT #1
If you want to have the same check for all protected routes, you should generate a middleware with php artisan make:middleware CheckResourceAccessMiddleware and use the same in your route.
In CheckResourceAccessMiddleware's handle method
// Here is our custom logic check occurs before login
if ($this->userIsnotAuthorized()) { // All your logic checks are inside 'userIsnotAuthorized()' method. Use any function or static check here
return redirect()->to('/static/page'); // redirect to static page which indicates unauthorized user note
}
return $next($request); // proceed to your page as user is authorized
to register the middleware edit your app/Http/Kernel.php and add this line to $routeMiddleware array
protected $routeMiddleware = [
...
'resource_access' => \App\Http\Middleware\CheckResourceAccessMiddleware::class,
];
After this step., you can use the middleware in any routes you want to protect
Route::get('/protected', [Controller::class, 'method'])->middleware('resource_access');
OR
// Middleware will be applied to all routes inside it
Route::middleware('resource_access')->group(function () {
Route::get('/protected', [Controller::class, 'method']);
// all other protected routes will be here
});
I found different approaches for this problem, Later I Found the best solution, as mention below,
In App\Middlewear\Authenticate.php, I have to change from return route('login');
to return route('my_custom_page_route');
From my custom page I can redirect it to auth login page easily.
Thank you everyone who suggest the best solutions.

Laravel Change URL First page Routes

I have an Laravel 5.4 Website with User Login.
If i enter the Url the script redirect to Login page, not "home" of course.
I want now an new Page if i enter the URL not Login Page. An Page with Login Button and after it goes to Login page. I have created an new blade where i want as first page: start.blade.php
How i can change this?
I have try it with my code in web.php but dont work, my Code:
Route::group(['middleware' => 'auth'],function(){
Route::get('logout','AuthController#Logout')->name('logout');
Route::get('/', 'HomeController#index')->name('home');
Route::get('myprofile','ProfileController#Index')->name('profile');
You have to add a new route for your page outside the group :
Route::get('start','tController#start')->name('start');
Route::group(['middleware' => 'auth'],function(){
Route::get('logout','AuthController#Logout')->name('logout');
Route::get('/', 'HomeController#index')->name('home');
Route::get('myprofile','ProfileController#Index')->name('profile');
}
And then you have to change in the Exceptions->Handler.php :
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(route('login')); // <-- change here :)
}
You have to change return redirect()->guest(route('login')); to your new route :)
return redirect()->guest(route('start'));
Add a new route in your routes.php file with no middleware attached to it. Use this:-
Route::get('start','StartController#start')->name('start');
Now your routes.php file should looks like this :-
// Newly added route for handling pre-login calls.
Route::get('start','StartController#start')->name('start');
Route::group(['middleware' => 'auth'],function(){
Route::get('logout','AuthController#Logout')->name('logout');
Route::get('/', 'HomeController#index')->name('home');
Route::get('myprofile','ProfileController#Index')->name('profile');
});
You need to create a new controller StartController with a function named start to achieve this without disturbing current structure of code.
start function in controller:-
public function start() {
return view('< new view name here >');
}

Laravel Passport post route test on postman

I set up Laravel Passport and started to create a few Get routes to get some data, that worked fine.
Now I am trying to post to get on auth token, which currently does not work:
This is my route which I call (Get route works, Post route does not work):
Route::group(['middleware' => 'auth:api'], function ()
{;
Route::get('users', ['as' => 'users', 'uses' => 'ApiController#users']);
Route::post('login/{id}/{name}', ['as' => 'login', 'uses' => 'ApiController#login']);
});
The method in my ApiController looks currently like this:
public function login(Request $request, $id, $name)
{
if($request->isMethod('post'))
{
$id = $request->id;
$name = $request->name;
$inquiry = new Inquiry();
$inquiry->user_id = $id;
$inquiry->user_name = $name;
if($inquiry->save())
{
return redirect()->route('inquiry.index')->with('success', 'Success.');
}
else
{
return redirect()->route('inquiry.index')->with('error', 'An error accured.')->withInput();
}
}
else
{
dd("Use Post.");
}
}
I tried to call it with following options:
Edit
I somehow managed to get this work after many hours, but still dont understand something.
First I did following:
public function callback(Request $request)
{
dd($request->code) // this holds a token I need for the code parameter in the post
...
With that I could get the token for the code parameter, but I think there is a better way to do that.
And finally this is now how I get the access + refresh token:
But there has to be a better way to get the code token of the callback request ($request->code), instead of dumping it and copying it.
The problem is that you have your login route inside a route group with auth:api on it. This means the user needs to be authenticated to even be able to authenticate. Just remove the login route outside the group and you should be fine.
You should call the Passport::routes method within the boot method of your AuthServiceProvider. This method will register the routes necessary to issue access tokens and revoke access tokens, clients, and personal access tokens:
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
/oauth/authorize route is already defined by the Passport::routes method. You do not need to manually define this route.

Protect routes with middleware Laravel

I have implemented middleware roles and permissions control in my app, but I cannot figure out why it only allows me to define one '/' route. The second one is still pointing to '/home' even though I override AuthController redirectTo variable.
My routes:
Route::group(['middleware' => 'role:user'], function()
{
Route::get('/', 'ScoresController#user');
});
Route::group(['middleware' => 'role:admin'], function()
{
Route::get('/', 'PagesController#home');
});
In any case after authentication user with user role redirecting to '/home'.
Like Simon says your second route will override the first one what you could do is load another controller wich redirects you to another page via redirect()
or write it as a route itself.
Could look like this:
Route::get('/', function(){
$user = Auth::user();
if($user->is('admin') {
return redirect('admin');
}else{
return redirect('user');
}
});
Route::get('admin', ['middleware' => 'role:admin', 'uses'=> 'PagesController#home']);
This is just one of many possibilities hope it helps you.

Redirect to Login page if ther user not logged in Laravel

I am using Laravel version 5. I have a route file for my project which contains plenty of lines. I need to put authentication like Redirect to login page if the user is not logged in. And I also want to prevent direct URL access if the user not logged in. What can I do?
And I have used below code
Route::group(array('before' => 'auth'), function(){
Route::get('/', 'HomeController#index');
});
But this prevents only for home page. I need to protect All my routes. And also suggest me how to reduce route file lines.
You can put as many routes in a Group as you like to
Route::group(array('before' => 'auth'), function(){
Route::get('/', 'HomeController#index');
Route::post('store', 'HomeController#store');
Route::get('show', 'AnotherController#index');
// ...
});
If you really need to protect all your routes, you could add
public function __construct()
{
$this->middleware('auth');
}
To your main controller class, Http/Controllers/Controller
Edit for your comment, taken from the docs, you may use
return redirect()->intended('view');
/**
* Handle an authentication attempt.
*
* #return Response
*/
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password]))
{
return redirect()->intended('dashboard');
}
}
}

Resources