How can I use HTTP basic Authentication and have the user submit their Username and Password in a HTML form and have it Authenticate using HTTP Basic Authentication.
I heard that Internet Explorer no longer supports the use of http://user:password#website.com no more so I don't know the best way to approach this.
Use of PHP and javascript and HTML is OK. I don't want to use PERL and I perfer no big javascript libs.
If you don't think HTTP Basic Auth. is the best way, please recommend something easy and simple to do. It will only be a login site for 5-6 people. No need to complicate it.
jQuery library has ajax function which has "password" and "user" parameter for Authentication. When user click login you can get value of login and password and passed to $.ajax function.
$('#submit').click(function() {
$.ajax({
url: 'authenticated.php',
username: $('#login').val(),
password: $('#passwd').val(),
success: function(data) {
//do something with data from the server
}
});
return false;
});
IMHO, the whole point of using HTTP authentication is being able to delegate authentication tasks:
The web server takes care of denying unauthorized access to protected resources
The browser takes care of asking for username and password when required
So you have a working system with minimum effort.
Now, if you use an HTML form to ask for credentials, the server will know who you are but the browser won't: it'll ask for credentials as soon as it finds the WWW-Authenticate response header and the 401 status code. For this to work, the browser has to send an Authorization request header on every HTTP request; however, your form cannot instruct the browser to send the appropriate HTTP header.
Of course, you can write your own server-side authentication code in PHP, configure the server to parse static files through it and omit 401 and WWW-Authenticate as soon as you get valid credentials (which then need to be stored somewhere else, e.g., a PHP session). But then you've lost all the advantages of HTTP authentication: at this point, a custom login handler with PHP sessions will be a much easier solution.
To sum up:
If you need simplicity, forget about HTML forms
If you need HTML forms, write your own code
If i understand you correctly you need to use .htpasswd with .htaccess: http://tools.dynamicdrive.com/password/
How can I use HTTP basic Authentication and have the user submit their Username and Password in a HTML form
No way.
please recommend something easy and simple to do.
sessions, cookies.
google for PHP auth tutorial and get over 9000 articles
oh well, one of them
<?
if (isset($_POST['auth_name'])) {
$name=mysql_real_escape_string($_POST['auth_name']);
$pass=mysql_real_escape_string($_POST['auth_pass']);
$query = "SELECT * FROM users WHERE name='$name' AND pass='$pass'";
$res = mysql_query($query) or trigger_error(mysql_error().$query);
if ($row = mysql_fetch_assoc($res)) {
session_start();
$_SESSION['user_id'] = $row['id'];
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
}
header("Location: http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
exit;
}
if (isset($_GET['action']) AND $_GET['action']=="logout") {
session_start();
session_destroy();
header("Location: http://".$_SERVER['HTTP_HOST']."/");
exit;
}
if (isset($_REQUEST[session_name()])) session_start();
if (isset($_SESSION['user_id']) AND $_SESSION['ip'] == $_SERVER['REMOTE_ADDR']) return;
else {
include 'your design here.php';
?>
<form method="POST">
<input type="text" name="auth_name"><br>
<input type="password" name="auth_pass"><br>
<input type="submit"><br>
</form>
<?
}
exit;
?>
intended to be put into file and called as require '/path/auth.php'; at the top of your scripts
Related
What I want to do is have a form that checks login information, and then, if the information is not right, it would redirect me back to the page where the login form was, but showing a p element that says something like "wrong username/password".
Is there any way I can do this? Or is there any way I can do the login check using only jQuery/ajax?
I have been trying to solve this for the past few hours, but I just could not get it right. Please bear in mind that I am a newbie in the field of web programming so don't be too harsh if there is an obvious answer to my question.
Credentials should be stored on your server.
Using ajax, on form submit:
Make ajax request to php with the users name and password
Have php verify authentication
If invalid return message to JavaScript
javascript can alert user if invalid, else it can change the location appropriately
Return from your server a 401 Unauthorized response code (see here: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error)
You can return the code using a PHP header directive: http://php.net/manual/en/function.header.php
In your javascript function, add an error callback and update the DOM as you see fit.
Yep, you can POST to a login form with ajax. I'll assume you have some form elements already and just need to post to the login page. You can create a post request like this:
xhttp=new XMLHttpRequest(); //make a request
xhttp.onreadystatechange=function() { //The request is asynchronous, this function will be executed once it completes
if (xhttp.readyState==4 && xhttp.status==200) {
if (xhttp.responseText==0) { //or whatever else your "error" is
document.getElementById("errorDisplayDiv").innerHTML = "Login failed!"; //show a login error text
}
else if (xhttp.responseText==1) { //login page reported a success
document.location = "usercontent.php"; //redirect to a page for logged in users
}
}
}
xhttp.open("POST","login.php",true); //post to your login page
xhttp.send(); //send it
So there are a couple of things you need here:
Username and password form on your login page that will be posted to login.php
A login.php (or ASP, whatever) that verifies the username and password and records that the client is logged in
A usercontent.php page that verifies that the user is logged in and displays the proper content, or redirects them to the login page if they aren't.
This was just a quick answer, please comment if you need details on any of this.
Along with what dm03514 said, don't try to authorize users on the client side - anyone can view the source and figure out the credentials. Here's a very simple AJAX implementation using jQuery:
http://jsfiddle.net/UTCbM/
The 'url' (check_username.php) should contain the logic for processing the username and password. This can be via a database, or something as simple as this (but not recommended):
<?php
$users = array(
'user1' => 'password1',
'user2' => 'password2'
);
if ($users[$_POST['username']] == $_POST['password']) {
die(json_encode('login_success.php'));
}
die(json_encode(False));
?>
Things to note:
1) Don't store passwords in plaintext. If you're using PHP, check out Bcrypt:
http://phpmaster.com/why-you-should-use-bcrypt-to-hash-stored-passwords/
At the very least, hash and salt your passwords.
2) This jsfiddle doesn't do SSL, which you should strongly consider for logging in to a public site
3) You'll have to add 'dataType':'json' to the AJAX call (I forgot in the fiddle) if you want to return data as JSON.
4) By evaluating the AJAX response, you can display the appropriate error message in the .login-errors DIV. This is just a quick example.
Finally, if you're doing this on a public site, PLEASE read up on some security best practices in regards to storing/accessing login credentials. If this is beyond what you're looking for, consider reading up on access control via .htpasswd
Again, this is a VERY simple implementation, I would not go live with something like this, but hopefully it will get you started.
Edit: For clarity, the 'error' message returned is because of the 'error' function being called since the AJAX won't work on the fiddle. You'll actually want to code your error messages into the 'success' function, as counter-intuitive as it may seem at first.
I wrote a working php authentication script for my HTTP file Server. Now, I want to write a login page with some nice graphics. I usually write my pages in HTML5, javacscript, and CSS. I am not sure how to implement the php authentication script. So far I have two ways I think I know of:
Write the login page in html5 and javascript, use ajax call to the php script after user enters name/password in input boxes, pass the username and password to the script, and have php return ether true or false depending on if that user was authenticated. Problem is, I do not know how to get php return true or false to javascript.
Write a PHP front controller model where the index.php loads html5, javascript, and css for graphics and if user is authenticated then redirect to the normal index.html document for the html file server. The problem with this is I am not familiar with using php as the front controller and I don't know if I can dynamically change elements with javascript for special effects just as if it was a normal html5 page.
You can use jQuery library for making Ajax request.
Request will look this way (it's javascript):
function submitLogin(enteredUsername, enteredPassword) {
$.post('login.php', {username: enteredUsername, password:enteredPassword},
function(response) {
if (response.result == true) {
// success code here
} else {
// fail code here
}
}, 'json');
}
login.php file should have this code:
<?php
$username = $_POST['username'];
$password = $_POST['password'];
//... check username and password here
echo json_encode(array('result' => true)); // this is response, true or false
exit;
?>
After doing alot of asking around on freenode, I found it is best to hide the documents outside of web root and have a server side script like php serve them itself after user authentication from the index.php.
I could use auth_basic from nginx, but I wanted a stronger encryption or hash - hence a server scripting language. I suppose the big fishes like facebook use webserver authentication like auth_basic module...but a much more customized and developed version. So, in my situation I will place the files outside of web root.
I would suggest the first solution. You can use http://api.jquery.com/jQuery.post/
to get your php return to javascript.
i am writing web-services for login script. Which i have to keep on HTTPS server. in general we are getting username & password on server side as
if(isset($_REQUEST['login'])){
$user=mysql_escape_string($_REQUEST['username']);
$password=hash('sha512',$_REQUEST['password']);
}
But this is fine for HTTP connection.
I have never used HTTPS connection for web services, So i want to know Is there some other way to pass username & password over HTTPS connection? So how to retrieve data from that request.
My client wants to send these data in header information some thing like
Method: POST
Content-Type: application/x-www-form-urlencoded
Content: username=mynames&password=abcabc
And from here i need to retrieve data.i have no idea about this.
HTTPS is effectively transparent to PHP code. It's entirely handled by the browser and the server. You can access the $_REQUEST variables exactly the same as with an HTTP request.
Edit (slightly modified question):
If your client wants you to have a login form to submit the username and password (as your changes to the question indicate), you just make form inputs the same as you would normally in an HTTP connection. Name them "username" and "password", respectively, and then pull their data from $_POST on the page you're posting the form to. Setting up the server to respond on HTTPS will make it handle everything else transparently, as I mentioned previously.
You can use HTTP Auth Basic to authenticate request.
Do not use HTTP auth, as Piotr mentions.
As someone else posted: Just set the vhost up to run on https and you're good to go. You could add something like this to verify the connection is secure:
<?php
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] && isset($_POST) && isset($_POST['login'])) {
// Your username and password verification here.
}
Please use $_POST though. $_REQUEST is a nasty way of saying "I don't really know what I'm doing here...".
So I've got a Backbone application + web homepage. Right now, if you login to my website, I create a global object with your user details from the database. However, you can still just hit one of the routes in the application directly.
How should I handle users who are not "logged in" and redirect them to a "you must login page"?
Is this a standard operation? Basically, I have a REST url setup that returns just
{ sessionId: [php-session-id-here] }
If they are logged in, it would return something more like this:
{
sessionId: [php-sess-id],
userId: [user-id-from-db],
firstName: [f-name],
lastName: [l-name]
}
Ideas? Thanks!
What I've done in the past is to include on every page along with jQuery (actually, added to the jQuery file) an extension on the AJAX method to check for a custom code that I send when a user isn't logged in. When that value was seen it redirected the user to the login page regardless of what was going down.
This was because that site had a time out on login, so a user could get logged out while sitting on a page and then the AJAX request would just fail. If you don't have a timeout on the login the odds of ever seeing this issue are slim. Just ignore requests that come from users that aren't logged in.
If you need help coding this, start here: Extending Ajax: Prefilters, Converters, and Transports.
Really shouldn't require anything as complex as pseudo-code:
JS needs to do some AJAX, so JS talks to server
PHP checks for login if needed
If not logged in, send back the abort message (I used a converter to catch a "notLoggedIn" dataType. However this could also be done with a transport, they are just more complex.)
JS sees the abort message and does a window.location redirect rather than return AJAX message.
If you want, you could load a lightbox with a login form and send that via AJAX to PHP where a re-login can take place, if you remember the AJAX attempt that failed you can send it again after login. Then the user doesn't even need to leave the page to log back in.
If you're using jQuery, you can set a global ajaxSetting that allows you to do certain things upon certain http codes. Some pages I read recommend adding to your JSON a url field to point to where to login, but I figure that's just up to you. So the only modifications you'd need to implement what I've mentioned is 1. change the http code to something reasonable like 401 (unauthorized) and implement the http code handler. But I wouldn't call this standard, I'd just say that's what several people have done (including myself).
<?php
function IsLoggedIn()
{
if(isset($_SESSION['id'])) // Change that to what you want
{
return 1;
}
else
{
return 0;
}
}
?>
Then in your code, you could use something like:
if(isLogged()){ header('Location: http://google.com'); }
What is the correct way to log out of HTTP authentication protected folder?
There are workarounds that can achieve this, but they are potentially dangerous because they can be buggy or don't work in certain situations / browsers. That is why I am looking for correct and clean solution.
Mu. No correct way exists, not even one that's consistent across browsers.
This is a problem that comes from the HTTP specification (section 15.6):
Existing HTTP clients and user agents typically retain authentication
information indefinitely. HTTP/1.1. does not provide a method for a
server to direct clients to discard these cached credentials.
On the other hand, section 10.4.2 says:
If the request already included Authorization credentials, then the 401
response indicates that authorization has been refused for those
credentials. If the 401 response contains the same challenge as the
prior response, and the user agent has already attempted
authentication at least once, then the user SHOULD be presented the
entity that was given in the response, since that entity might
include relevant diagnostic information.
In other words, you may be able to show the login box again (as #Karsten says), but the browser doesn't have to honor your request - so don't depend on this (mis)feature too much.
Method that works nicely in Safari. Also works in Firefox and Opera, but with a warning.
Location: http://logout#yourserver.example.com/
This tells browser to open URL with new username, overriding previous one.
The simple answer is that you can't reliably log out of http-authentication.
The long answer:
Http-auth (like the rest of the HTTP spec) is meant to be stateless. So being "logged in" or "logged out" isn't really a concept that makes sense. The better way to see it is to ask, for each HTTP request (and remember a page load is usually multiple requests), "are you allowed to do what you're requesting?". The server sees each request as new and unrelated to any previous requests.
Browsers have chosen to remember the credentials you tell them on the first 401, and re-send them without the user's explicit permission on subsequent requests. This is an attempt at giving the user the "logged in/logged out" model they expect, but it's purely a kludge. It's the browser that's simulating this persistence of state. The web server is completely unaware of it.
So "logging out", in the context of http-auth is purely a simulation provided by the browser, and so outside the authority of the server.
Yes, there are kludges. But they break RESTful-ness (if that's of value to you) and they are unreliable.
If you absolutely require a logged-in/logged-out model for your site authentication, the best bet is a tracking cookie, with the persistence of state stored on the server in some manner (mysql, sqlite, flatfile, etc). This will require all requests to be evaluated, for instance, with PHP.
Workaround
You can do this using Javascript:
<html><head>
<script type="text/javascript">
function logout() {
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
// code for IE
else if (window.ActiveXObject) {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
if (window.ActiveXObject) {
// IE clear HTTP Authentication
document.execCommand("ClearAuthenticationCache");
window.location.href='/where/to/redirect';
} else {
xmlhttp.open("GET", '/path/that/will/return/200/OK', true, "logout", "logout");
xmlhttp.send("");
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {window.location.href='/where/to/redirect';}
}
}
return false;
}
</script>
</head>
<body>
Log out
</body>
</html>
What is done above is:
for IE - just clear auth cache and redirect somewhere
for other browsers - send an XMLHttpRequest behind the scenes with 'logout' login name and password. We need to send it to some path that will return 200 OK to that request (i.e. it shouldn't require HTTP authentication).
Replace '/where/to/redirect' with some path to redirect to after logging out and replace '/path/that/will/return/200/OK' with some path on your site that will return 200 OK.
Workaround (not a clean, nice (or even working! see comments) solution):
Disable his credentials one time.
You can move your HTTP authentication logic to PHP by sending the appropriate headers (if not logged in):
Header('WWW-Authenticate: Basic realm="protected area"');
Header('HTTP/1.0 401 Unauthorized');
And parsing the input with:
$_SERVER['PHP_AUTH_USER'] // httpauth-user
$_SERVER['PHP_AUTH_PW'] // httpauth-password
So disabling his credentials one time should be trivial.
Logout from HTTP Basic Auth in two steps
Let’s say I have a HTTP Basic Auth realm named “Password protected”, and Bob is logged in. To log out I make 2 AJAX requests:
Access script /logout_step1. It adds a random temporary user to .htusers and responds with its login and password.
Access script /logout_step2 authenticated with the temporary user’s login and password. The script deletes the temporary user and adds this header on the response: WWW-Authenticate: Basic realm="Password protected"
At this point browser forgot Bob’s credentials.
My solution to the problem is the following. You can find the function http_digest_parse , $realm and $users in the second example of this page: http://php.net/manual/en/features.http-auth.php.
session_start();
function LogOut() {
session_destroy();
session_unset($_SESSION['session_id']);
session_unset($_SESSION['logged']);
header("Location: /", TRUE, 301);
}
function Login(){
global $realm;
if (empty($_SESSION['session_id'])) {
session_regenerate_id();
$_SESSION['session_id'] = session_id();
}
if (!IsAuthenticated()) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.$_SESSION['session_id'].'",opaque="'.md5($realm).'"');
$_SESSION['logged'] = False;
die('Access denied.');
}
$_SESSION['logged'] = True;
}
function IsAuthenticated(){
global $realm;
global $users;
if (empty($_SERVER['PHP_AUTH_DIGEST']))
return False;
// check PHP_AUTH_DIGEST
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
!isset($users[$data['username']]))
return False;// invalid username
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
// Give session id instead of data['nonce']
$valid_response = md5($A1.':'.$_SESSION['session_id'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
if ($data['response'] != $valid_response)
return False;
return True;
}
Typically, once a browser has asked the user for credentials and supplied them to a particular web site, it will continue to do so without further prompting. Unlike the various ways you can clear cookies on the client side, I don't know of a similar way to ask the browser to forget its supplied authentication credentials.
The only effective way I've found to wipe out the PHP_AUTH_DIGEST or PHP_AUTH_USER AND PHP_AUTH_PW credentials is to call the header HTTP/1.1 401 Unauthorized.
function clear_admin_access(){
header('HTTP/1.1 401 Unauthorized');
die('Admin access turned off');
}
Trac - by default - uses HTTP Authentication as well. Logout does not work and can not be fixed:
This is an issue with the HTTP authentication scheme itself, and there's nothing we can do in Trac to fix it properly.
There is currently no workaround (JavaScript or other) that works with all major browsers.
From: http://trac.edgewall.org/ticket/791#comment:103
Looks like that there is no working answer to the question, that issue has been reported seven years ago and it makes perfect sense: HTTP is stateless. Either a request is done with authentication credentials or not. But that's a matter of the client sending the request, not the server receiving it. The server can only say if a request URI needs authorization or not.
I needed to reset .htaccess authorization so I used this:
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if user hits Cancel button';
exit;
}
?>
Found it here :
http://php.net/manual/en/features.http-auth.php
Go figure.
A number of solutions reside on that page and it even notes at the bottom: Lynx, doesn't clear the auth like other browsers ;)
I tested it out on my installed browsers and once closed, each browser seems like it consistently requires reauth on reentry.
This might be not the solution that was looked for but i solved it like this.
i have 2 scripts for the logout process.
logout.php
<?php
header("Location: http://.#domain.com/log.php");
?>
log.php
<?php
header("location: https://google.com");
?>
This way i dont get a warning and my session is terminated
AFAIK, there's no clean way to implement a "logout" function when using htaccess (i.e. HTTP-based) authentication.
This is because such authentication uses the HTTP error code '401' to tell the browser that credentials are required, at which point the browser prompts the user for the details. From then on, until the browser is closed, it will always send the credentials without further prompting.
The best solution I found so far is (it is sort of pseudo-code, the $isLoggedIn is pseudo variable for http auth):
At the time of "logout" just store some info to the session saying that user is actually logged out.
function logout()
{
//$isLoggedIn = false; //This does not work (point of this question)
$_SESSION['logout'] = true;
}
In the place where I check for authentication I expand the condition:
function isLoggedIn()
{
return $isLoggedIn && !$_SESSION['logout'];
}
Session is somewhat linked to the state of http authentication so user stays logged out as long as he keeps the browser open and as long as http authentication persists in the browser.
Maybe I'm missing the point.
The most reliable way I've found to end HTTP Authentication is to close the browser and all browser windows. You can close a browser window using Javascript but I don't think you can close all browser windows.
While the others are correct in saying that its impossible to logout from basic http authentication there are ways to implement authentication which behave similarly. One obvious appeoach is to use auth_memcookie. If you really want to implement Basic HTTP authentication (i.e. use the browser dialogs for logging in trather than an HTTP form) using this - just set the authentication to a seperate .htaccess protected directory containing a PHP script which redirects back where te user came after createing the memcache session.
There's a lot of great - complex - answers here. In my particular case i found a clean and simple fix for the logout. I have yet to test in Edge.
On my page that I have logged in to, I have placed a logout link similar to this:
logout
And in the head of that logout.html page (which is also protected by the .htaccess) I have a page refresh similar to this:
<meta http-equiv="Refresh" content="0; url=https://logout:logout#MyDomainHere.net/" />
Where you would leave the words "logout" in place to clear the username and password cached for the site.
I will admit that if multiple pages needed to be able to be directly logged in to from the beginning, each of those points of entry would need their own corresponding logout.html page. Otherwise you could centralize the logout by introducing an additional gatekeeper step into the process before the actual login prompt, requiring entry of a phrase to reach a destination of login.
I have summarised my solution in an article (https://www.hattonwebsolutions.co.uk/articles/how_to_logout_of_http_sessions) however I have used an ajax call and 2x htaccess files (as suggested in this question: How to logout of an HTTP authentication (htaccess) that works in Google Chrome?).
In short - you:
Create a sub folder with an htaccess file on the same AuthName but require a different user
Send an ajax request to the page (with the wrong username) (which fails) and then trigger a timeout redirect to the logged out page.
This avoids having a secondary popup in the logout folder requesting another username (which would confuse users). My article uses Jquery but it should be possible to avoid this.