I want to redirect users back to the login page if they attempt to access certain pages on my site. I want to create a general rule so that I do not have to implement it on every page for every url separately.
For example if user try to access /profile , I want them to redirect back to login page if they are not logged in. I tried doing this using group routes by putting an if condition but that did not work. Moreover I am not an expert in laravel. This is what I tried.
Route::group(['prefix' => '/users'], function () {
if(Auth::user()){
Route::get('/','FacebookControllers\FacebookPagesController#listUsers');
Route::get('{id}/profile', 'FacebookControllers\FacebookPagesController#userProfile');
}
else {
return redirect('/');
}
});
Check out laravel's Auth middleware.
Documentation here: laravel.com/docs/5.1/routing#route-groups
Example (taken from the docs):
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});
Related
I am using Azure AD along with asp.net core mvc. The following code is the same with a default MVC project generated with Work or School Accounts authentication.
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
Everything works just fine for the most time. The app is basically a notepad. A user logs in and adds notes/tasks. Everything after logging in is done using ajax requests. After some time the app stops working because there is a need for authentication again. Note that if I refresh the page everything is working again.
Am I doing this right? Am I missing something or this kind of use case is not supported.
Should I just create a javascript function that will auto refresh the page after some time?
Should I just create a javascript function that will auto refresh the page after some time?
You could try to create a hidden iframe in all the templates used by the Web App to make automatic calls to a MVC controller method that forces a call to renew the authentication data on a regular basis.
This is achieved very easily by configuring an automatic javascript process in the front-end executed in a loop on a regular basis of 45'. This value could be configured or extracted from a configuration file too. The only key condition is that it must be less than one hour.
Here is the simplified example code related to MVC Controller:
/* Action method, inside "Account" controller class, to force renewal of user authentication session */
public void ForceSignIn()
{
HttpContext.GetOwinContext().Authentication.Challenge(new AuthenticationProperties { RedirectUri = "/" },
OpenIdConnectAuthenticationDefaults.AuthenticationType);
}
And here is the simplified example HTML and javascript code employed to call silently in a hidden iframe to MVC Controller:
<iframe id="renewSession" hidden></iframe>
<script>
setInterval( function ()
{ #if (Request.IsAuthenticated) {
<text>
var renewUrl = "/Account/ForceSignIn";
var element = document.getElementById("renewSession");
element.src = renewUrl;
</text>
}
},
1000*60*45
);
</script>
For more details, you could refer to this article which get the similar situation with you.
I found a simple solution by accident. My goal was to hit a check endpoint every minute and If I get a 302 status code I would redirect the user to the authentication page.
public IActionResult Check()
{
return Ok(new { });
}
I left the developer tools open and noticed that every 30 mins I get a bigger response.
And this actually refreshes the cookie and as a result there is no need to redirect the user.
So to sum up someone needs to do this check every 40-50 minutes because the expiration is set to ~1 hour by default.
How to keep the original url that the user was navigating to?
Say I have an unauthenticated user navigates to http://localhost:9000/customer/123
To authenticate the user I would do a:
// in my app.js
new Oidc.UserManager().signinRedirect({state:'customer/123'}); // need a way to keep this url
When that returns to the callback.html where I need a way of going to the origianal url:
// callback.html
<script src="oidc-client.js"></script>
<script>
Oidc.Log.logger = console;
new Oidc.UserManager().signinRedirectCallback().then(function () {
var state = 'customer/123' // how to do a redirect to the page originally requested page?
window.location.href="http://localhost:9000/ + state
}).catch(function (e) {
console.error(e);
});
</script>
Or maybe there are other build in ways of getting the origianl url?
Thanks for any help!
Your approach is good. You sign in the way you are doing it, and then in the callback, slightly modify your code (use the user object that is returned):
new Oidc.UserManager().signinRedirectCallback().then(function (user){
var url = user.state;
//more code here
}
The state will be part of the user object, and will have the value that you have submited. And you can redirect to wherever you want.
I want to make simple application using laravel5.2 in which there will come sign in form on base url when i log in to the application there need to give a different view i.e. Client dashboard at same url. How can i do that Please help me. Thanks In Advance !
You could do something like this for root / URL:
Route::get('/', function(){
if (!Auth::check()) {
return View::make('login'); // login view if not authenticated
// or call controller for login
}
else{
return View::make('dashboard'); // dashboard view if authenticated
// or call controller for dashboard
}
});
This is very simple. You have to just make a function in WelcomeController or in other controller. And do check if user is already login or not and redirect to proper view page accordingly.
For example :
In your routes.php file write route like this
$router->get('/',array(
'as' => 'home',
'uses' => 'WelcomeController#welcome'
));
And in your controller ,in case of this example : WelcomeController make a function named welcome and do some auth check like this
public function welcome()
{
if(Auth::check()){
//get some data for user dashboard
return view('dashboard');
}
return view('login');
}
PS: for good practice, use dependency injection. In this case inject Guard
class instead of using Auth facade.
I have this problem, my application should redirect users to admin area whose routes are protected (have middle auth). When I login it redirects to login page again but when place the dashboard route outside the route group, it behaves well. What may be the problem? This is my code:
Code for protected route (does not work) after login
Route::group(['middleware'=>'auth'], function(){
Route::get('backend/dashboard', array('as'=>'dashboard', 'uses'=>'BackendDashboardController#getDashboard'));
});
Code for dashboard route placed outside the route group (Works well after login)
Route::get('backend/dashboard', array('as'=>'dashboard', 'uses'=>'BackendDashboardController#getDashboard'));
Auth controller - Post login function
protected function postLogin() {
$request = Input::all();
$user = array(
'email' => $request['email'],
'password' => $request['password']
);
if ($this->auth->attempt($user)) {
return redirect(route('dashboard'));
}else{
return redirect(route('login'));
}
}
I really want to protect my admin routes and place all of them under auth middleware. Kindly avice
It only redirects, if you are not authorize/loggedin, otherwise it works fine.
and I think you are missing something in Route::group() you also need to mention the prefix eg
Route::group(['prefix'=>'backend', 'middleware'=>'auth'], function(){
Route::get('dashboard', array('as'=>'dashboard', 'uses'=>'BackendDashboardController#getDashboard'));
});
Edited
Also try to update your attempt method, then try it, eg:
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
Right now I am trying to test my controllers and I need to access session, I found out that you can login using superagent but my only option for loggin in to the web app is through google oauth, and right now I cannot find any appropriate samples for testing with Mocha. Any help?
It depends on how you implemented your sessions.
In my Sails app, after authentication, I set req.session.authenticated = true, along with cookies, etc. One thing you can do if you're doing something similar is in your /login route, add:
if (process.env.NODE_ENV === 'test') {
req.session.authenticated = true;
// do what you would do next after authentication
} else {
// do normal login procedures
}
Then, in your tests, in a before hook, you can use superagent to make a request to the /login route to authenticate:
describe('MyController', function() {
var agent;
before(function (done) {
agent = require('superagent').agent('YOUR_APP_URL');
// authenticate
agent
.post('/login')
.end(done)
});
// in your tests, use the same agent to make future requests
describe('#someAction', function() {
it('should do something', function(done) {
agent.
.post('someAction')
.end(function (err, res) {
// should work!
});
});
});
});
It's just an idea - you can adapt this approach to however you're checking sessions. This works for my Sails app using Mocha for tests.