Login Form For Http Basic Auth

2020-02-10 18:19发布

问题:

I am running a Perl application named bitlfu.For login it is using something like Apache HTTP Basic Auth but not a form.I want to make form for the login with username and password field. I have tried JavaScript and PHP with no results till now.

So I need help!

PS: this kind of url works

http://user:password@host.com

回答1:

I think a simple JavaScript like:

document.location='http://' + user + ':' + pass + '@mydomain.tld';

should do the work.

So basically, you have to create a form, with a user and pass field, then onsubmit, use the part of JavaScript given here:

<form method="post" onsubmit="javascript:document.location='http://' + $('login') + ':' + $('pass') + '@mydomain.tld';">
    <input type="text" name="login" id="login" />
    <input type="password" name="pass" id="pass" />
    <input type="submit" value="ok"/>
</form>

where $() is a document.getElementById or jquery or so. I used the $() function to make the code shorter. Here is an implementation, which does not work on every browser. Again, look throw jQuery for cross browser solution.

function $(_id) { return document.getElementById(_id); }

Otherwise, you can use php and redirect the user with a header location.

php way:

<?php

if (isset($_POST['login']) && isset($_POST['password'])) { header('Location: ' . urlencode($_POST['login']) . ':' . urlencode($_POST['password']) . '@domain.tld'); }
else
{
?>
<form method="post" onsubmit="javascript:document.location='http://' + $('login') + ':' + $('pass') + '@mydomain.tld';">
    <input type="text" name="login" id="login" />
    <input type="password" name="pass" id="pass" />
    <input type="submit" value="ok"/>
</form>

<?php
}


回答2:

You can redirect the user to http://user:password@host.com with Perl, or using JavaScript. I don't know Perl so I'll show you the JS:

function submitted() {
    document.location = "http://" + document.getElementById("username").value + ":" + document.getElementById("password").value + "@host.com";
}

<form onSubmit="submitted">...blablabla...</form>

This should work. The only problem is that this shows the password in the URL.


The awesome AJAX way using jQuery:

$.ajax({
   'url': 'http://host.com/',
   //'otherSettings': 'othervalues',
   username: $("username").val(),
   password: $("password").val()
   },
   sucess: function(result) {
     alert('done');
   }
});

The ultimate Perl way (I think)

$username = # somehow get username
$password = # somehow get password
use CGI;
my $query=new CGI;
print $query->redirect('http://host.com/');


回答3:

The method of explicitly redirecting document.location with username@password in URL caused me some problems with Safari giving a phishing warning.

If I instead first make an AJAX request to a URL with basic auth headers added, and then redirect document.location without the username/pass in the URL then it worked better for me

Example

<script
  src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
    integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g="
      crossorigin="anonymous"></script>
<script>
$(document).ready(function() {
    $('form').submit(function() {
        $.ajax({
            url: 'https://efishgenomics.integrativebiology.msu.edu/collaborators/',
            username: $("#login").val(),
            password: $("#pass").val()
        }).done(function() {
            $("#error_msg").html("");
            document.location='https://efishgenomics.integrativebiology.msu.edu/collaborators/';
        }).fail(function(result) {
            console.error(result);
            $("#error_msg").html("Error logging in: "+result.statusText);
        });
        return false;
    });
});
</script>



<div id="error_msg" style="color: red"></div>

<form method="post">
    Username:
    <input type="text" name="login" id="login" />
    Password:
    <input type="password" name="pass" id="pass" />
    <input type="submit" value="Submit"/>
</form>

Unfortunate caveat with Safari only, if you type your username and password incorrectly, then it makes another standard HTTP basic auth popup, but this is better than a big red "Phishing warning" that occurs when you make the document.location include username/pass

Chrome doesn't have duplicate popup if login credentials are incorrect though



回答4:

This is a simple plug&play solution ;-). Will work for any domain (and on HTTPS too):

<script>
function submitAuthForm() {
    var login = document.getElementById('login').value;
    var pass = document.getElementById('pass').value;
    location = location.href.replace('://', '://' + encodeURIComponent(login) + ':' + encodeURIComponent(pass) + '@');
    // might be required to reload on Firefox (FF shows confirmation dialog)
    setTimeout(function(){
        location.reload(true);
    }, 5000);
}
</script>
<form method="get" onsubmit="submitAuthForm(); return false">
    <input type="text" id="login" />
    <input type="password" id="pass" />
    <input type="submit" value="OK" />
</form>

You can drop this in your 401 error document.

Note that return false is required so that the page is not reloaded twice.