How to redirect after logout from Laravel Middleware? - redirect

I'm writing some middleware in Laravel (version 8.0) which essentially checks for a deactivated organisation when an API route is called and it will log them out with the intention of redirecting to the sign in page with an appropriate message.
However, when the redirect runs it throws the following error:
The PUT method is not supported for this route. Supported methods: GET, HEAD.
The reason is because the API route being executed is a PUT method in this case so when it tries to run the redirect which expects a GET method it does not work.
Here is my middleware:
public function handle(Request $request, Closure $next): mixed
{
if (Auth::check() && Auth::user()) {
if($this->statusChecker::isServiceProviderDeactivated(Auth::user()['service_provider_id'])) {
auth()->guard('web')->logout();
(new SsoBroker())->logout();
return response()->redirectTo('/sign-in');
}
}
return $next($request);
}
The logout executes correctly (so if the user refreshes the page they are taken to the sign-in page) but the redirect does not work. I am not particularly experienced in writing middleware and I've done lots of research on this but not really finding any solutions. Since this site is a one-page react project the issue could lie there, but I am not sure. If anyone has any ideas I would appreciate it.

change the Route method instead of put to get/post
Route::get('/', [Auth::class, 'login'])

Related

CakePHP 3 allow only REST index.json and and.json (no normal views) with Auth

I've created the blog from blog tutorial, and I would to protect articles list, but I want that this be accesible across REST, I've activated json extensions.
All works well. I can add and retrieve list, but now I want to deny index and add from web and only be accesible from .json to public.
I tried with
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow('index.json');
}
But this obviously doesn't work. All webpage is login protected as is in tutorial. Web services should be accesible to Android App (code is ready and working).
Thank you!
Of course that doesn't work, the allow() methods expects valid method names, and that's all the authentication component cares about, method/action names, it doesn't matter how the action was requested.
What you are trying to do requires you to check the type of the request, and based on the results, allow the actions. Checking the request type can be done using Request::is().
See Cookbook > Request & Response Objects > Checking Request Conditions
So it might be as simple as
if ($this->request->is('json')) {
$this->Auth->allow(['index', 'add']);
}

How to redirect to last action in sailsjs using req.session?

I am creating a login application where I need to redirect back to previous url from where the login action was called. I need to know does sails provide a built-in method by using which I can redirect to previous action without creating my own helper function.
You can put this line in your policy if the users fails authentication and requires a login
if(req.method.toLowerCase() === 'get') req.session.afterLoginGoTo = req.originalUrl;
The above line makes sure they are doing a GET request as anything else provides another layer of complexity.
Then after you log the person in you can check for that and re-route
if(req.session.afterLoginGoTo) return res.redirect(req.session.afterLoginGoTo);
else res.redirect('/defaultHomePage');
Just get the origin request from req and then use res.redirect()

Play Framework: Don't change URL after form validation failed

In a plain Play application I have the following scenario.
A route file which looks like this:
GET /accounts/add controllers.Accounts.add()
POST /accounts controllers.Accounts.create()
The first route results in a view where I can add a new account. The form to submit the new account looks something like this:
#helper.form(action = routes.Accounts.create()) {...}
Now the controller binds the input to the form and checks for any validation errors:
public static Result create() {
Form<Account> form = Form.form(Account.class).bindFromRequest();
if (form.hasErrors()) {
return badRequest(views.html.account.add.render(form));
}
...
}
Now the thing is, the client will see the same view with some additional error messages. However, meanwhile the URL has changed from http://example.com/accounts/add to http://example.com/accounts.
If the client now reloads the browser this calls GET http://example.com/accounts (which isn't even mapped in this scenario - thus getting a 404 - Not Found).
Maybe it's just me but I find this kind of annoying and browsing some GitHub projects I couldn't find a good solution for this case.
Of cause things would be much simpler if the second route is rewritten to:
POST /accounts/add controllers.Accounts.create()
... in which case everything works fine. But from a REST point of view this doesn't feel good either. The same applies to update scenarios (having GET /accounts/:id/update vs. PUT /accounts/:id).
Is there a guide on how to handle this? Am I getting something wrong or is this no problem at all (from a pragmatic point of view)?
It's not possible to leave the previous URL because a request for a new address has already been made. A controller only provides response for a requested resource. To go to the previous URL you could only make a redirect in case of validation failure but you would lost errors that way so this is not a solution.
I suggest mapping both actions with the same URL. This way you would solve problem with the browser reload.
If you create a REST service for http clients that aren't browsers you will probably want to serve different response than a simple http page. The separation of actions for particular clients could be a good solution for keeping REST API clean and a browser user happy.

App with no DB: You must call the "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" class

First things first. I'm a complete OAuth newbie. This will be my first stab at it, and things are getting hairy...
I'm writing a single page application using Durandal & Web API.
The user needs to be able to login using any social network.
I don't have access to a database whatsoever, I have to call an unprotected 3rd party web service which I consume server-side, and need to protect using OAuth.
So I've managed to add the files to my solution which generates the login using facebook contol/button (created a new MVC4 web application, and did a manual copy and paste of all the auth related files, updated bootstrappers etc..), and the code seems to work for the most part.
When facebook redirects back to
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(this.Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return this.RedirectToAction("ExternalLoginFailure");
}
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
{
return this.RedirectToLocal(returnUrl);
}
//code removed for brevity ....
}
I get the error specified once the following line tries to execute.
OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false)
I've removed the [InitializeSimpleMembership] attribute from the controller, as I don't have a database.
Please forgive me if this is the dumbest question ever, but...
Why does the login fail? I mean at that point, isn't the app trying to log into facebook, why does it need a databse? Or am I correct in saying I can remove/replace that code section, with a login/authorise call on the web-service I'm using?
Not the dumbest question ever. Not by a long shot. But you are getting the error because your membership provider is still set to use the SimpleMembershipProvider and OAuthWebSecurity will use the default membership provider. If you don't want to use a database you will have to create or find a different membership provider to use.
EDIT:
I know you said you don't have access to a DB but if you can use SQL Compact you can just stick with the default SimpleMembershipProvider(check out Hanselman's blog) or DevArt has a SQLLite provider. Also the MemFlex Project has a RavenDb provider. If none of those work I think you might just have to write your own.

What event to hook to redirect on 404 errors? Symfony 1.4

I am using symfony 1.4.
I need to redirect certain urls when 404 error occurs.
Let's say user is looking for a url http://example.com/oldurl and it doesn't exist I want to check if this url is set for redirect.
If url is set to be redirected I would like to redirect it to that url.
QUESTION: Which event should I hook into to get info about the requested url, that got redirected to 404 error page ?
P.S We only want to check for redirection if page doesn't exist. We do not want to run "the check" for every request, only when page not found!
thanks a lot!
Symfony fire an event each time a page is not found: controller.page_not_found.
You can find it in the documentation: http://www.symfony-project.org/reference/1_4/en/15-Events#chapter_15_sub_controller_page_not_found
Edit:
You can retrieve the url in the method that listen to this event by calling the context. With something like that:
$context = sfContext::hasInstance() ? sfContext::getInstance() : null;
if(null !== $context)
{
$requested_url = $context->getRequest()->getUri();
}
You can give a closer look to the plugin sfErrorNotifierPlugin, it catches exception and 404 error and send an email for a report. Look at how they handle 404 error.
I don't know where to hook exactly inside the execution stack, but I know the general cleaner way through routing. If you are doing routing without still having in code the default routing rule (which you shouldn't by practice since), then it would be as simple as the following in your app routing.yml (at the end):
catch_all:
url: /*
param: { module: yourModule, action: handleNotFound }