How can I set CSRF in a form in Appcelerator? - laravel-5

I am creating an app that has a login. I want that login to match the username and password but I cannot make it happen because I cannot send the "_token" field, and I cant because I cannot generate the same token that the application will wait for.
This is my current form:
<View id="loginView" layout="vertical">
<TextField id="inputUsername" />
<TextField id="inputPassword" passwordMask="true" />
<Button id="buttonLogin" onClick="performLogin" />
<ActivityIndicator id="activityIndicator" />
</View>
This is my current login request on Appcelerator.
loginReq.open("POST","http://192.168.100.29/miapp/mobile/auth/login");
var params = {
username: $.inputUsername.value,
password: $.inputPassword.value
};
loginReq.send(params);
And it should be something like:
loginReq.open("POST","http://192.168.100.29/miapp/mobile/auth/login");
var params = {
username: $.inputUsername.value,
password: $.inputPassword.value,
_token: $.inputTokenOrSomething.value
};
loginReq.send(params);
Also I created a route in the routes.php file in Laravel, as follows:
Route::get("mobile/auth/login", function(){
echo ("Debug"); exit;
});
Does anyone has an idea? Thank you.

Normally you want to send a CSRF Token via a Request Header. This is how it's done with Appcelerator when sending a token to Drupal:
loginReq.open("POST","URL");
loginReq.setRequestHeader('X-CSRF-Token',TOKENHERE);
loginReq.send(params);
Note, your Request Header goes AFTER open, but BEFORE send.
Edit:
Forgot to add - Normally you send a log in without a token, then capture the token from the servers response after a successful log in (usually sent as XML, JSON, etc... depending on the set up). This token is stored and sent in the request headers anytime you need to authenticate yourself to perform an action (like posting, deleting content). Again, this all depends on the set up.

Related

Send multiple file inputs to the server without a form

With a form and the following input tag:
<input type="file" name="images" multiple="" class="inputFileHidden">
I can get the file images on my server just by simply searching through the request.files object:
images = request.files.getlist('images') // returns list of imgs.
In my case, I'm not working with a form, but rather I post it using AJAX.
With simple things like text I can easily post it as such:
Client side
const i_post_title = document.getElementsByName('post_title')[0];
....
$.post('/_upload_post', {
title_post: i_post_title.value
}).done(function(data){
console.log(data)
}).fail(function(){
console.log('fail')
})
And receive it on my server by accessing the request.form object and passing in the key of the payload sent from the client:
Server Side
title_post = request.form['title_post']
But with files, how should I handle it without having a form?

Yammer javascript SDK logout issue

I can successfully login with yam.platform.login but when I call
yam.getLoginStatus(
function (response) {
if (response.authResponse) {
yam.platform.logout(function (response) {
if (response) {
alert("logout success");
}
})
}
}
);
the inner callback function is never reached. Do people know what is happening?
EDIT: another strange behavior that could be related to the problem: after the above logout function call, the login status is still "connected" and I checked in Chrome that all cookies from yammer.com are deleted. But when I manually ask Chrome to delete the cookies, login status would return "unconnected".
Response from yam.platform.logout seems "false" after successful logout so you might try "if(response == false)" or even without if statement..
I was also facing the same issue. It is hard to believe that the issue still exists in 2018! I dug a bit more and found that after the app is authorized by user, Yammer server sends a cookie which gets stored in the browser somewhere (not tied to the session) and yam.platform.logout is unable to delete this cookie (Ideally it should!)
But I found a good workaround which is working neatly for me.
Below is JS in my login page:
$("#yammer-login").click(function(){
console.log("clicked");
yam.getLoginStatus(
function(resp) {
yam.platform.login(function (response) { //prompt user to login and authorize your app, as necessary
if (response.authResponse) {
console.dir(response); //print user information to the console
alert("login success");
}
$.ajax({
type:"POST",
url:"/setSession",
data:JSON.stringify(response,null,'\t'),
contentType:"application/json;charset=UTF-8",
success: function(result){
alert("Result from setSession is: "+result);
window.location.replace("/login");
}});
});
}
);
});
Here #yammer-login is the id for login element
<h2 class="sign-in">
<center>
Sign-in With Yammer
<br><br>
<span id="yammer-login">Click</span>
</center>
</h2>
Here is my workflow:
The JS on login page sends a POST request to setSession and sets the session. The execution of window.location.replace("/login"); sends a GET request to my server for /login url. As the session is now set, my server then redirects this request to the dashboard. After I click on logout button on the dashboard. I clear all the session cookies and redirect it back to the login page. As the session is now un-set- I see the login page again! All works smooth!
So, the next time user clicks on #yammer-login DOM element - the session gets set and she gets redirected to dashboard (this time without authorizing the app)!
Hope this helps someone who faces this issue like me in the future!

How to handle authentication in Angular JS application

I am implementing an auth system in my angular js app.
What I am planning it like below:
Get user info(name and pass from login form)
Check whether user exists or not
if exists server respond with a session cookie and frontend will redirect to a certain page.
then user will do some task which will generate API request
API request should have cookie information that was sent on step 3
server check whether the cookie was generated or not and if cookie was found then respond with the API request results. And in my service I am doing something like
MyApp.service('myAuth', function($http, $q) {
this.authHeader = null;
this.checkAuth = function(){
//do api call and if success sets this.authHeader = response
}
this.isAuthenticaed = function(){
this.authHeader ? return this.authHeder : return false;
}
After submitting the login form I will call checkAuth and get my session cookie back from my server, how I can add the cookie information while doing the next REST call and also when user will navigate throughout the application after log in I do want to check each time isAuthenticaed true or false, in Angularjs when it will navigate to another page does it resets after setting it true from the first call? And is my approach 1-6 good or do you have any specific suggestions?
Btw I checked previous so entries but those are not what I want to know.
I am not sure about your backend, but this is how I would do it
Create a separate login page (dedicated url not angular sub view or
modal dialog).
If the user is not authenticated redirect to this login
page. This is done by server redirects. This page may or may not use
angular framework, as it just involves sending a user\password to
server.
Make a POST (not AJAX request) from the login page, and verify on server.
On the server set the auth cookie. (Different frameworks do it differently. ASP.Net sets form authentication cookie.)
Once the user is authenticated redirect user to the actual angular app and load all its components.
This saves any code require to manage authentication on client side in Angular. If the user lands on this page he is authenticated and has the cookie.
Also default browser behavior is to send all cookies associated with a domain with each request, so you don't have to worry if angular is sending some cookie or not.
I use the http-auth-interceptor. http://ngmodules.org/modules/http-auth-interceptor
In my backend (asp.net mvc) I build a simple Authentication Service and return an http error 401 if the user is not authenticated.
Then I handle the error with a login-view in the SPA site.
The ideas put forth by the previous answers will work, but I think they're overkill. You don't need anything this complex.
how I can add the cookie information while doing the next REST call
Turn on withCredentials by default inside $httpProvider like so:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]);
Then remove the wildcard (if you had one) from the CORS-related headers, and set allow-credentials, on the server side. In my case, using Python + Flask + Flask-Restful, it's super easy and looks like this:
import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
api.decorators = [cors.crossdomain(origin='http://localhost:8100', credentials=True)]
Now cookies will be set and returned automatically and transparently by the browser. See these threads for more info:
$http response Set-Cookie not accessible
Angularjs $http does not seem to understand "Set-Cookie" in the response
when user will navigate throughout the application after log in I do want to check each time isAuthenticaed true or false
As suggested above, have the server return 401 if the auth session expires or is deleted, and use $httpInterceptor in Angular to catch this like so:
app.config(function($httpProvider) {
var interceptor =
function($q, $rootScope) {
return {
'response': function(response) {
return response;
},
'responseError': function(rejection) {
if (rejection.status==401) {
// Modify this part to suit your needs.
// In my case I broadcast a message which is
// picked up elsewhere to show the login screen.
if (!rejection.config.url.endsWith('/login'))
{
$rootScope.$broadcast('auth:loginRequired');
}
}
return $q.reject(rejection)
}
}
};
$httpProvider.interceptors.push(interceptor);
});
(Disclosure: I'm one of the developers of UserApp)
You could use the third-party service UserApp for this, together with the AngularJS module.
Check out the getting started guide, or take the course on Codecademy. Here's some examples of how it works:
Login form with error handling:
<form ua-login ua-error="error-msg">
<input name="login" placeholder="Username"><br>
<input name="password" placeholder="Password" type="password"><br>
<button type="submit">Log in</button>
<p id="error-msg"></p>
</form>
User info is accessed using the user service: user.current.email
Or in the template: <span>{{ user.email }}</span>
Signup form with error handling:
<form ua-signup ua-error="error-msg">
<input name="first_name" placeholder="Your name"><br>
<input name="login" ua-is-email placeholder="Email"><br>
<input name="password" placeholder="Password" type="password"><br>
<button type="submit">Create account</button>
<p id="error-msg"></p>
</form>
ua-is-email means that the username is the same as the email.
How to specify which routes that should be public, and which route that is the login form:
$routeProvider.when('/login', {templateUrl: 'partials/login.html', public: true, login: true});
$routeProvider.when('/signup', {templateUrl: 'partials/signup.html', public: true});
The .otherwise() route should be set to where you want your users to be redirected after login. Example:
$routeProvider.otherwise({redirectTo: '/home'});
Log out link:
<a href="#" ua-logout>Log Out</a>
Hide elements that should only be visible when logged in:
<div ng-show="user.authorized">Welcome {{ user.first_name }}!</div>
And to authenticate to your back-end services, just use user.token() to get the session token and send it with the AJAX request. At the back-end, use the UserApp API to check if the token is valid or not.
If you need any help, just let me know :)

Django - Start Session by Ajax Request

I need to know how to start a session by Ajax in Django. I'm doing exactly as described bellow, but it is not working! The request is sent correctly, but don't start any session. If a request directly without ajax it works! What is going on?
'# urls
r'^logout/$', 'autenticacao.views.logout_view'
'# view of login
def login_view(request):
username = request.GET.get('username', '')
password = request.GET.get('password', '')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse(user.get_profile().sos_user.name)
return HttpResponse('user invalido')
'# ajax in a html page
$(function(){
$.get('http://localhost:8000/logout/?username=usuario?>&password=senha', function(data){
alert(data);
});
You're not calling the login_view. You're ajax request is going to the /logout/ url which is calling the autenticacao.views.logout_view.
Also, The ?> after username=usuario doesn't look right in the your get url.
My guess is you should be doing something like http://localhost:8000/login/?username=usuario&password=senha. (but I'd need to see your login url mapping to be sure).
Also, you should be POSTing the login information and using HTTPS for security reasons, but that's a different issue.

How can I get browser to prompt to save password?

Hey, I'm working on a web app that has a login dialog that works like this:
User clicks "login"
Login form HTML is loaded with AJAX and displayed in DIV on page
User enters user/pass in fields and clicks submit. It's NOT a <form> -- user/pass are submitted via AJAX
If user/pass are okay, page reloads with user logged in.
If user/pass are bad, page does NOT reload but error message appears in DIV and user gets to try again.
Here's the problem: the browser never offers the usual "Save this password? Yes / Never / Not Now" prompt that it does for other sites.
I tried wrapping the <div> in <form> tags with "autocomplete='on'" but that made no difference.
Is it possible to get the browser to offer to store the password without a major rework of my login flow?
thanks
Eric
p.s. to add to my question, I'm definitely working with browers that store passwords, and I've never clicked "never for this site" ...this is a technical issue with the browser not detecting that it's a login form, not operator error :-)
I found a complete solution for this question. (I've tested this in Chrome 27 and Firefox 21).
There are two things to know:
Trigger 'Save password', and
Restore the saved username/password
1. Trigger 'Save password':
For Firefox 21, 'Save password' is triggered when it detects that there is a form containing input text field and input password field is submitted. So we just need to use
$('#loginButton').click(someFunctionForLogin);
$('#loginForm').submit(function(event){event.preventDefault();});
someFunctionForLogin() does the ajax login and reload/redirect to the signed in page while event.preventDefault() blocks the original redirection due to submitting the form.
If you deal with Firefox only, the above solution is enough but it doesn't work in Chrome 27. Then you will ask how to trigger 'Save password' in Chrome 27.
For Chrome 27, 'Save password' is triggered after it is redirected to the page by submitting the form which contains input text field with attribute name='username' and input password field with attribute name='password'. Therefore, we cannot block the redirection due to submitting the form but we can make the redirection after we've done the ajax login. (If you want the ajax login not to reload the page or not to redirect to a page, unfortunately, my solution doesn't work.) Then, we can use
<form id='loginForm' action='signedIn.xxx' method='post'>
<input type='text' name='username'>
<input type='password' name='password'>
<button id='loginButton' type='button'>Login</button>
</form>
<script>
$('#loginButton').click(someFunctionForLogin);
function someFunctionForLogin(){
if(/*ajax login success*/) {
$('#loginForm').submit();
}
else {
//do something to show login fail(e.g. display fail messages)
}
}
</script>
Button with type='button' will make the form not to be submitted when the button is clicked.
Then, binding a function to the button for ajax login. Finally, calling $('#loginForm').submit(); redirects to the signed-in page. If the signed-in page is current page, then you can replace 'signedIn.xxx' by current page to make the 'refresh'.
Now, you will find that the method for Chrome 27 also works in Firefox 21. So it is better to use it.
2. Restore the saved username/password:
If you already have the loginForm hard-coded as HTML, then you will found no problem to restore the saved password in the loginForm.
However, the saved username/password will not be bind to the loginForm if you use js/jquery to make the loginForm dynamically, because the saved username/password is bind only when the document loads.
Therefore, you needed to hard-code the loginForm as HTML and use js/jquery to move/show/hide the loginForm dynamically.
Remark:
If you do the ajax login, do not add autocomplete='off' in tag form like
<form id='loginForm' action='signedIn.xxx' autocomplete='off'>
autocomplete='off' will make the restoring username/password into the loginForm fails because you do not allow it 'autocompletes' the username/password.
Using a button to login:
If you use a type="button" with an onclick handler to login using ajax, then the browser won't offer to save the password.
<form id="loginform">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="doLogin" type="button" value="Login" onclick="login(this.form);" />
</form>
Since this form does not have a submit button and has no action field, the browser will not offer to save the password.
Using a submit button to login:
However, if you change the button to type="submit" and handle the submit, then the browser will offer to save the password.
<form id="loginform" action="login.php" onSubmit="return login(this);">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="doLogin" type="submit" value="Login" />
</form>
Using this method, the browser should offer to save the password.
Here's the Javascript used in both methods:
function login(f){
var username = f.username.value;
var password = f.password.value;
/* Make your validation and ajax magic here. */
return false; //or the form will post your data to login.php
}
I have been struggling with this myself, and I finally was able to track down the issue and what was causing it to fail.
It all stemmed from the fact that my login form was being dynamically injected into the page (using backbone.js). As soon as I embed my login form directly into my index.html file, everything worked like a charm.
I think this is because the browser has to be aware that there is an existing login form, but since mine was being dynamically injected into the page, it didn't know that a "real" login form ever existed.
This solution worked for me posted by Eric on the codingforums
The reason why it does not prompt it is because the browser needs the page to phyiscally to refresh back to the server. A little trick you can do is to perform two actions with the form. First action is onsubmit have it call your Ajax code. Also have the form target a hidden iframe.
Code:
<iframe src="ablankpage.htm" id="temp" name="temp" style="display:none"></iframe>
<form target="temp" onsubmit="yourAjaxCall();">
See if that causes the prompt to appear.
Eric
Posted on http://www.codingforums.com/showthread.php?t=123007
Simple 2020 aproach
This will automatically enable autocomplete and save password in browsers.
autocomplete="on" (form)
autocomplete="username" (input, email/username)
autocomplete="current-password" (input, password)
<form autocomplete="on">
<input id="user-text-field" type="email" autocomplete="username"/>
<input id="password-text-field" type="password" autocomplete="current-password"/>
</form>
Check out more at Apple's documentation:
Enabling Password AutoFill on an HTML Input Element
There's an ultimate solution to force all browsers (tested: chrome 25, safari 5.1, IE10, Firefox 16) to ask for save the password using jQuery and ajax request:
JS:
$(document).ready(function() {
$('form').bind('submit', $('form'), function(event) {
var form = this;
event.preventDefault();
event.stopPropagation();
if (form.submitted) {
return;
}
form.submitted = true;
$.ajax({
url: '/login/api/jsonrpc/',
data: {
username: $('input[name=username]').val(),
password: $('input[name=password]').val()
},
success: function(response) {
form.submitted = false;
form.submit(); //invoke the save password in browser
}
});
});
});
HTML:
<form id="loginform" action="login.php" autocomplete="on">
<label for="username">Username</label>
<input name="username" type="text" value="" autocomplete="on" />
<label for="password">Password</label>
<input name="password" type="password" value="" autocomplete="on" />
<input type="submit" name="doLogin" value="Login" />
</form>
The trick is in stopping the form to submit its own way (event.stopPropagation()), instead send your own code ($.ajax()) and in the ajax's success callback submit the form again so the browser catches it and display the request for password save.
You may also add some error handler, etc.
Hope it helped to someone.
I tried spetson's answer but that didn't work for me on Chrome 18. What did work was to add a load handler to the iframe and not interrupting the submit (jQuery 1.7):
function getSessions() {
$.getJSON("sessions", function (data, textStatus) {
// Do stuff
}).error(function () { $('#loginForm').fadeIn(); });
}
$('form', '#loginForm').submit(function (e) {
$('#loginForm').fadeOut();
});
$('#loginframe').on('load', getSessions);
getSessions();
The HTML:
<div id="loginForm">
<h3>Please log in</h3>
<form action="/login" method="post" target="loginframe">
<label>Username :</label>
<input type="text" name="login" id="username" />
<label>Password :</label>
<input type="password" name="password" id="password"/>
<br/>
<button type="submit" id="loginB" name="loginB">Login!</button>
</form>
</div>
<iframe id="loginframe" name="loginframe"></iframe>
getSessions() does an AJAX call and shows the loginForm div if it fails. (The web service will return 403 if the user isn't authenticated).
Tested to work in FF and IE8 as well.
The browser might not be able to detect that your form is a login form. According to some of the discussion in this previous question, a browser looks for form fields that look like <input type="password">. Is your password form field implemented similar to that?
Edit: To answer your questions below, I think Firefox detects passwords by form.elements[n].type == "password" (iterating through all form elements) and then detects the username field by searching backwards through form elements for the text field immediately before the password field (more info here). From what I can tell, your login form needs to be part of a <form> or Firefox won't detect it.
None of the answers already make it clear you can use the HTML5 History API to prompt to save the password.
First, you need to make sure you have at least a <form> element with a password and email or username field. Most browsers handle this automatically as long as you use the right input types (password, email or username). But to be sure, set the autocomplete values correctly for each input element.
You can find a list of the autocomplete values here: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete
The ones you need are: username, email and current-password
Then you have two possibilities:
If you navigate away to a different URL after submitting, most browsers will prompt to save the password.
If you don't want to redirect to a different URL or even reload the page (e.g. a single page application). Just prevent the event defaults (using e.preventDefault) in your submit handler of the form. You can use the HTML5 history API to push something on the history to indicate you 'navigated' inside your single page application. The browser will now prompt to save the password and username.
history.pushState({}, "Your new page title");
You can also change the page's URL, but that is not required to prompt to save the password:
history.pushState({}, "Your new page title", "new-url");
Documentation: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
This has the additional benefit that you can prevent the browser to ask to save the password if the user entered the password incorrectly. Note that in some browsers the browser will always ask to save the credentials, even when you call .preventDefault and not use the history API.
If you don't want to navigate away and/or modify the browser history, you can use replaceState instead (this also works).
I spent a lot of time reading the various answers on this thread, and for me, it was actually something slightly different (related, but different). On Mobile Safari (iOS devices), if the login form is HIDDEN when the page loads, the prompt will not appear (after you show the form then submit it). You can test with the following code, which displays the form 5 seconds after the page load. Remove the JS and the display: none and it works. I am yet to find a solution to this, just posted in case anyone else has the same issue and can not figure out the cause.
JS:
$(function() {
setTimeout(function() {
$('form').fadeIn();
}, 5000);
});
HTML:
<form method="POST" style="display: none;">
<input name='email' id='email' type='email' placeholder='email' />
<input name='password' id='password' type='password' placeholder='password' />
<button type="submit">LOGIN</button>
</form>
The following code is tested on
Chrome 39.0.2171.99m: WORKING
Android Chrome 39.0.2171.93: WORKING
Android stock-browser (Android 4.4): NOT WORKING
Internet Explorer 5+ (emulated): WORKING
Internet Explorer 11.0.9600.17498 / Update-Version: 11.0.15: WORKING
Firefox 35.0: WORKING
JS-Fiddle:
http://jsfiddle.net/ocozggqu/
Post-code:
// modified post-code from https://stackoverflow.com/questions/133925/javascript-post-request-like-a-form-submit
function post(path, params, method)
{
method = method || "post"; // Set method to post by default if not specified.
// The rest of this code assumes you are not using a library.
// It can be made less wordy if you use one.
var form = document.createElement("form");
form.id = "dynamicform" + Math.random();
form.setAttribute("method", method);
form.setAttribute("action", path);
form.setAttribute("style", "display: none");
// Internet Explorer needs this
form.setAttribute("onsubmit", "window.external.AutoCompleteSaveForm(document.getElementById('" + form.id + "'))");
for (var key in params)
{
if (params.hasOwnProperty(key))
{
var hiddenField = document.createElement("input");
// Internet Explorer needs a "password"-field to show the store-password-dialog
hiddenField.setAttribute("type", key == "password" ? "password" : "text");
hiddenField.setAttribute("name", key);
hiddenField.setAttribute("value", params[key]);
form.appendChild(hiddenField);
}
}
var submitButton = document.createElement("input");
submitButton.setAttribute("type", "submit");
form.appendChild(submitButton);
document.body.appendChild(form);
//form.submit(); does not work on Internet Explorer
submitButton.click(); // "click" on submit-button needed for Internet Explorer
}
Remarks
For dynamic login-forms a call to window.external.AutoCompleteSaveForm is needed
Internet Explorer need a "password"-field to show the store-password-dialog
Internet Explorer seems to require a click on submit-button (even if it's a fake click)
Here is a sample ajax login-code:
function login(username, password, remember, redirectUrl)
{
// "account/login" sets a cookie if successful
return $.postJSON("account/login", {
username: username,
password: password,
remember: remember,
returnUrl: redirectUrl
})
.done(function ()
{
// login succeeded, issue a manual page-redirect to show the store-password-dialog
post(
redirectUrl,
{
username: username,
password: password,
remember: remember,
returnUrl: redirectUrl
},
"post");
})
.fail(function ()
{
// show error
});
};
Remarks
"account/login" sets a cookie if successful
Page-redirect ("manually" initiated by js-code) seems to be required. I also tested an iframe-post, but I was not successful with that.
I found a fairly elegant solution (or hack, whatever fits) for Prototype.JS users, being one of the last holdouts using Prototype. A simple substitution of corresponding jQuery methods should do the trick.
First, make sure there's a <form> tag, and a submit button with a class name that can be referenced later (in this case faux-submit) that is nested inside an element with a style set to display:none, as illustrated below:
<form id="login_form" action="somewhere.php" method="post">
<input type="text" name="login" />
<input type="password" name="password" />
<div style="display:none">
<input class="faux-submit" type="submit" value="Submit" />
</div>
<button id="submit_button">Login</button>
</form>
Then create a click observer for the button, that will "submit" the form as illustrated:
$('submit_button').observe('click', function(event) {
$('login_form').submit();
});
Then create a listener for submit event, and stop it. event.stop() will stop all submit events in the DOM unless it's wrapped in Event.findElement with the class of the hidden input button (as above, faux-submit):
document.observe('submit', function(event) {
if (event.findElement(".faux-submit")) {
event.stop();
}
});
This is tested as working in Firefox 43 and Chrome 50.
Your site is probably already in the list where the browser is told not to prompt for saving a password. In firefox, Options -> Security -> Remember password for sites[check box] - exceptions[button]
add a bit more information to #Michal Roharik 's answer.
if your ajax call will return a return url, you should use jquery to change the form action attribute to that url before calling form.submit
ex.
$(form).attr('action', ReturnPath);
form.submitted = false;
form.submit();
I had similar problem, login was done with ajax, but browsers (firefox, chrome, safari and IE 7-10) would not offer to save password if form (#loginForm) is submitted with ajax.
As a SOLUTION I have added hidden submit input (#loginFormHiddenSubmit) to form that was submitted by ajax and after ajax call would return success I would trigger a click to hidden submit input. The page any way needed to refreshed. The click can be triggered with:
jQuery('#loginFormHiddenSubmit').click();
Reason why I have added hidden submit button is because:
jQuery('#loginForm').submit();
would not offer to save password in IE (although it has worked in other browsers).
I have tried all the ways. Nothing works completely. This is my solution. It works for me. I hope it will work for you.
I replace the email/username input with a textarea
<form>
<textarea required placeholder="Email" rows=1></textarea>
<input required placeholder="Password" type="password" readonly onfocus="this.removeAttribute('readonly')" />
<button>
Sign in
</button>
Not every browser (e.g. IE 6) has options to remember credentials.
One thing you can do is to (once the user successfully logs in) store the user information via cookie and have a "Remember Me on this machine" option. That way, when the user comes again (even if he's logged off), your web application can retrieve the cookie and get the user information (user ID + Session ID) and allow him/her to carry on working.
Hope this can be suggestive. :-)
The truth is, you can't force the browser to ask. I'm sure the browser has it's own algorithm for guessing if you've entered a username/password, such as looking for an input of type="password" but you cannot set anything to force the browser.
You could, as others suggest, add user information in a cookie. If you do this, you better encrypt it at the least and do not store their password. Perhaps store their username at most.
You may attach the dialog to the form, so all those inputs are in a form. The other thing is make the password text field right after the username text field.
This work much better for me, because it's 100% ajaxed and the browser detects the login.
<form id="loginform" action="javascript:login(this);" >
<label for="username">Username</label>
<input name="username" type="text" value="" required="required" />
<label for="password">Password</label>
<input name="password" type="password" value="" required="required" />
<a href="#" onclick="document.getElementById("loginform").submit();" >Login</a>
</form>
Using a cookie would probably be the best way to do this.
You could have a checkbox for 'Remember me?' and have the form create a cookie to store the //user's login// info.
EDIT: User Session Information
To create a cookie, you'll need to process the login form with PHP.

Resources