Redirect to a different domain with Mojolicious - perl

at Route / of my page, the user can see a button:
<button>click me</button>
A click on this button will open a new tab and do a post to the "post_route".
in the controller sub of the post_route, i want to check some things and then redirect the user to a different domain, let's just say for example to www.redirecturl.com.
I also need to send payload to www.redirecturl.com (post request).
the domain www.redirecturl.com will then check the value i sent to it and render a specific page.
Unfortunately it doesn't work as expected.
If i use i.e. $self->redirect_to('www.redirecturl.com');
i get a "redirect error" in my browser with the information "This problem can sometimes occur when cookies are disabled or denied.".
So... any idea how i can redirect with Mojolicious to a completely different domain and send some payload in the body?
Thank you in advance

The documentation for redirect_to() gives the following examples:
$c = $c->redirect_to('named', foo => 'bar');
$c = $c->redirect_to('named', {foo => 'bar'});
$c = $c->redirect_to('/index.html');
$c = $c->redirect_to('http://example.com/index.html');
From which, we can guess that if you want to redirect to a different domain, then you need to give it a complete URI - not just a domain name.

Related

How can I redirect only my homepage to a different URL on a different server?

I am trying to redirect my company's home page (let's call it example.com) to a new webpage I built : example.net, without losing any archive and sub pages, i.e when a user navigates to example.com it will redirect to example.net, but when they click on "about us" I want it to go back to example.com/aboutus.
I can get it to redirect but every time a user clicks on a link (such as about us) the browser will try to load example.net/aboutus rather than example.com/aboutus, which does not exist.
I have tried many different redirect commands, 301 commands, .htaccess as well as adding redirects to the index page. Everytime I get the homepage to open to the new URL
I have attached my index page code.
<?php
/**
* Copyright 2013
* #author
*/
include_once($_SERVER["DOCUMENT_ROOT"]."/example.php");
//print_r($_SERVER);
$pageArr = explode("/", $_GET["q"]);
$_GET["q"] = $pageArr[0];
if($pageArr[1]){
$_GET["z"] = $pageArr[1];
}
if(!$_GET["q"]){
$_GET["q"] = "home";
}
$mDevice = null;
if($_GET["print"] == "true"){
$mDevice = "standard";
}
//Begin defining the main page
$WebPage = new xyWebpage($_GET["q"], $mDevice);
//$WebPage->setCharset("ISO-8859-1");
showPage();
function getPageName(){
return $_GET["q"];
}
?>
I'm not a PHP guy, but depending on your platform you can use either:
MOD_REWRITE Module for Apache or IIS re-write module.
Both of these support re-writing URL's which can match your use case.
I'm curious why you would just not replace your home page that you are redirected from on the same server(s), but in any case, since you already have the redirect working you only need it on the .net server. You will need two rules, one to stop processing if it's a root URL request, and then one for all other requests that will re-write the root back to your .com address. You need that first rule so you don't create a loop between your servers.

PhalconPHP - redirection to home page always adds /index in the URI

I'm working on my first app in PhalconPHP so I'm deep in the documentation while working, but this doesn't seem to be covered.
Let's say that my app is running on www.myapp.tld. In some situations I need to redirect the user back to the home page and for that I'm using the following code:
if ($haveToRedirect) {
$this->response->redirect();
$this->view->disable();
return;
}
Instead if redirecting to www.myapp.tld, the user is redirected to www.myapp.tld/index. I've tried different redirect calls, but all give the same result:
$this->response->redirect('');
$this->response->redirect('/');
$this->response->redirect('/', TRUE);
In the app's bootstrap I've set the BaseUri to be '/':
$di->set('url', function() {
$url = new Phalcon\Mvc\Url();
$url->setBaseUri('/');
return $url;
});
Is there a way to avoid "index" being added and just have it redirect to "www.myapp.tld"?
If a file is not specified, you will be directed to the index page in that directory by default. You need to specify a file location. Also try URI, not URL
The cause of redirection to "/index" was actually in the Permission class I made several weeks ago. It had:
$this->response->redirect('index');
for every controller that guest could not access to. Since I added new controllers I was continuously redirected to index, and noticed that redirect comes from somewhere else when I removed the conditional redirects I've put in the controller.
Anyway, this is it. Lesson learned - next time grep for 'index' before asking for help. :)

Web2Py Redirect after login

I'm trying to redirect the user to another page (default/news) after the login(on default/index) but no matter how much i tried i couldn't get it done. I'm using the login available in the navbar.
I've added this line to db.py
auth.settings.login_next=URL(r=request, c='default', f='news')
Everything in the default controller is the same it includes
def news():
message = "Welcome to News!"
return locals()
I've also tried with this
auth.settings.login_next=URL('news')
Which doesn't work either. Please Help.
Edit:
After searching for days i've found the answer here This is how you do it.
#In layout.html change
<ul id="navbar" class="nav pull-right">{{='auth' in globals() and auth.navbar(mode="dropdown") or ''}}</ul>
# to
<ul id="navbar" class="nav pull-right">{{='auth' in globals() and auth.navbar(mode="dropdown",referrer_actions=None) or ''}}</ul>
And again a change in db.py
#In db.py add these lines:
auth.settings.login_next = URL('news')
That worked for me.
The auth.settings.login_next URL is only a default in case there is no referrer already in the login URL (the referrer is in the "_next" query string variable). The navbar automatically includes a referrer in the auth action links (set to the URL of the current page) -- to override that, you can explicitly specify thereferrer_actions argument and exclude actions for which the referrer should not be set:
{{=auth.navbar(..., referrer_actions=['register', ...])}}
It's now April 2016, and while the original question is still highly relevant, it appears that web2py has changed and the modifications suggested above to layout.html are no longer relevant. There is no reference to "auth.navbar" in the standard layout.html.
The good news is, that all one needs to do is include the python code described above in the default.py controller and it works. Note, I put it in the 'user' function, I'm not sure if that is the best place to put it as most comments just say to put it in 'the controller', without specifying a function.
def user():
auth.settings.login_next = URL('default','dashboard')
return dict(form=auth())
I was able to redirect to a user's home page after login/signup by putting the following code in my product info page.
This way, when they get redirected back to the welcome-product-info page, I check to see if they came from login or signup and direct them to where they should go.
I'd love to find way to use auth.settings.login_next
#
def info():
# If just signed up or just logged in, go to the user's home page and not
# back to this product landing page that referred them
if auth.is_logged_in():
if '/default/user/login?_next=/fnd/home/info' in request.env.http_referer:
redirect( URL( 'user', 'show_campaigns') )
if '/default/user/register?_next=/fnd/home/info' in request.env.http_referer:
redirect( URL( 'user', 'show_campaigns') )
return dict()

WWW::Mechanize won't work after submit

At my work I build a lot of wordpress sites and I also do a lot of cutting and pasting. In order to streamline this process I'm trying to make a crawler that can fill out and submit form information to wordpress. However, I can't get the crawler to operate correctly in the wordpress admin panel once I'm past the login.
I know it works to submit the login form because I've gotten the page back before. But this script doesn't seem to return the "settings" page, which is what I want. I've been trying to use this site as a guide: www.higherpass.com/Perl/Tutorials/Using-Www-mechanize/3/ for how to use mechanize but I could use some additional pointers for this. Here is my Perl script, I've tried a few variations but I just need to be pointed in the right direction.
Thanks!
use WWW::Mechanize;
my $m = WWW::Mechanize->new();
$url2 = 'http://www.moversbatonrougela.com/wp-admin/options-general.php';
$url = 'http://www.moversbatonrougela.com/wp-admin';
$m->get($url);
$m->form_name('loginform');
$m->set_fields('username' => 'user', 'password' => 'password');
$m->submit();
$response = $m->get($url2);
print $response->decoded_content();
Put the below lines of code just before $m->submit(); . Since WWW::Mechanize is a subclass of LWP::UserAgent you can use any of LWP's methods.
$m->add_handler("request_send", sub { shift->dump; return });
$m->add_handler("response_done", sub { shift->dump; return });
The above would enable logging in your code. Look out for the Request/Response return codes i.e. 200 (OK) or 302 (Redirect) etc. The URL request i.e. the $m->get() is probably getting redirected or the machine's ip is Blocked by the server. If its a redirect, then you can probably use $m->redirect_ok(); to follow the redirect URL, or in case you don't want to follow the redirect URL use $m->requests_redirectable (this is an LWP method). The logs should show something like below-
HTTP/1.1 200 OK
OR
HTTP/1.1 302 Found
If none of the above works, use an alternative of $m->submit(); like below and give it a try-
my $inputobject=$mech->current_form()->find_input( undef, 'submit' );
$m->click_button(input => $inputobject);

Preventing form resubmission

Page one contains an HTML form. Page two - the code that handles the submitted data.
The form in page one gets submitted. The browser gets redirected to page two. Page two handles the submitted data.
At this point, if page two gets refreshed, a "Confirm Form Resubmission" alert pops up.
Can this be prevented?
There are 2 approaches people used to take here:
Method 1: Use AJAX + Redirect
This way you post your form in the background using JQuery or something similar to Page2, while the user still sees page1 displayed. Upon successful posting, you redirect the browser to Page2.
Method 2: Post + Redirect to self
This is a common technique on forums. Form on Page1 posts the data to Page2, Page2 processes the data and does what needs to be done, and then it does a HTTP redirect on itself. This way the last "action" the browser remembers is a simple GET on page2, so the form is not being resubmitted upon F5.
You need to use PRG - Post/Redirect/Get pattern and you have just implemented the P of PRG. You need to Redirect. (Now days you do not need redirection at all. See this)
PRG is a web development design pattern that prevents some duplicate form submissions which means, Submit form (Post Request 1) -> Redirect -> Get (Request 2)
Under the hood
Redirect status code - HTTP 1.0 with HTTP 302 or HTTP 1.1 with HTTP 303
An HTTP response with redirect status code will additionally provide a URL in the location header field. The user agent (e.g. a web browser) is invited by a response with this code to make a second, otherwise identical, request to the new URL specified in the location field.
The redirect status code is to ensure that in this situation, the web user's browser can safely refresh the server response without causing the initial HTTP POST request to be resubmitted.
Double Submit Problem
Post/Redirect/Get Solution
Source
Directly, you can't, and that's a good thing. The browser's alert is there for a reason. This thread should answer your question:
Prevent Back button from showing POST confirmation alert
Two key workarounds suggested were the PRG pattern, and an AJAX submit followed by a scripting relocation.
Note that if your method allows for a GET and not a POST submission method, then that would both solve the problem and better fit with convention. Those solutions are provided on the assumption you want/need to POST data.
The only way to be 100% sure the same form never gets submitted twice is to embed a unique identifier in each one you issue and track which ones have been submitted at the server. The pitfall there is that if the user backs up to the page where the form was and enters new data, the same form won't work.
There are two parts to the answer:
Ensure duplicate posts don't mess with your data on the server side. To do this, embed a unique identifier in the post so that you can reject subsequent requests server side. This pattern is called Idempotent Receiver in messaging terms.
Ensure the user isn't bothered by the possibility of duplicate submits by both
redirecting to a GET after the POST (POST redirect GET pattern)
disabling the button using javascript
Nothing you do under 2. will totally prevent duplicate submits. People can click very fast and hackers can post anyway. You always need 1. if you want to be absolutely sure there are no duplicates.
You can use replaceState method of JQuery:
<script>
$(document).ready(function(){
window.history.replaceState('','',window.location.href)
});
</script>
This is the most elegant way to prevent data again after submission due to post back.
Hope this helps.
If you refresh a page with POST data, the browser will confirm your resubmission. If you use GET data, the message will not be displayed. You could also have the second page, after saving the submission, redirect to a third page with no data.
Well I found nobody mentioned this trick.
Without redirection, you can still prevent the form confirmation when refresh.
By default, form code is like this:
<form method="post" action="test.php">
now, change it to
<form method="post" action="test.php?nonsense=1">
You will see the magic.
I guess its because browsers won't trigger the confirmation alert popup if it gets a GET method (query string) in the url.
The PRG pattern can only prevent the resubmission caused by page refreshing. This is not a 100% safe measure.
Usually, I will take actions below to prevent resubmission:
Client Side - Use javascript to prevent duplicate clicks on a button which will trigger form submission. You can just disable the button after the first click.
Server Side - I will calculate a hash on the submitted parameters and save that hash in session or database, so when the duplicated submission was received we can detect the duplication then proper response to the client. However, you can manage to generate a hash at the client side.
In most of the occasions, these measures can help to prevent resubmission.
I really like #Angelin's answer. But if you're dealing with some legacy code where this is not practical, this technique might work for you.
At the top of the file
// Protect against resubmits
if (empty($_POST)) {
$_POST['last_pos_sub'] = time();
} else {
if (isset($_POST['last_pos_sub'])){
if ($_POST['last_pos_sub'] == $_SESSION['curr_pos_sub']) {
redirect back to the file so POST data is not preserved
}
$_SESSION['curr_pos_sub'] = $_POST['last_pos_sub'];
}
}
Then at the end of the form, stick in last_pos_sub as follows:
<input type="hidden" name="last_pos_sub" value=<?php echo $_POST['last_pos_sub']; ?>>
Try tris:
function prevent_multi_submit($excl = "validator") {
$string = "";
foreach ($_POST as $key => $val) {
// this test is to exclude a single variable, f.e. a captcha value
if ($key != $excl) {
$string .= $key . $val;
}
}
if (isset($_SESSION['last'])) {
if ($_SESSION['last'] === md5($string)) {
return false;
} else {
$_SESSION['last'] = md5($string);
return true;
}
} else {
$_SESSION['last'] = md5($string);
return true;
}
}
How to use / example:
if (isset($_POST)) {
if ($_POST['field'] != "") { // place here the form validation and other controls
if (prevent_multi_submit()) { // use the function before you call the database or etc
mysql_query("INSERT INTO table..."); // or send a mail like...
mail($mailto, $sub, $body); // etc
} else {
echo "The form is already processed";
}
} else {
// your error about invalid fields
}
}
Font: https://www.tutdepot.com/prevent-multiple-form-submission/
use js to prevent add data:
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}