0

I'm writing a JavaScript function that needs to uphold three properties:

  • be very small and lightweight - no external libraries
  • encode a string in such a way as to be able to be passed as a GET parameter
  • this string must be decoded again at its destination

Effectively, it authenticates the user by sending his username and password to a PHP page which then verifies it. This is done via GET because I haven't yet found a way of doing a background cross-domain POST request. The trouble is that if the user has a character such as '#' or similar in his password, it doesn't get sent properly.

Currently to avoid this, I encode() the password string before sending it, which allows it to be received without problems. However, I read that PHP's urldecode() is not a perfect analog for this, as there are corner cases which are treated differently (i.e. ' ', '+', etc). Sadly I cannot find this document anymore, so I cannot quote it, but the gist was that one of them converts spaces into '+' signs, which the other treats as an actual plus sign, or something like that...

As such, I'm looking for a Javascript function that can take a string and make it URL-safe, and which has a perfect reversal function in PHP so that the original string can be recovered.

The arguably awful code I currently use to achieve this:

login.onsubmit = function(){
    loginFailMsg.style.display = 'none';
    var inputs = login.getElementsByTagName('input');
    var formdata = 
        'username='+inputs[0].value+'&password='+encode(inputs[1].value);
    submit.src = formtarget+'/auth/bklt?'+formdata;
    userinfo = undefined;
    setTimeout(getUserinfo,300);
    return false;
};
5
  • Now that you mentioned there's a very good reason for GET, why not remove that sentence and simply share that reason with us? Curious! Commented Oct 16, 2010 at 23:31
  • And, there's too much noise in your question! If you don't want MD5 (like you commented to Karl's answer), then why mention that, and why not remove the whole hashing from the title as well? Commented Oct 16, 2010 at 23:37
  • @Arjan: Apologies for the noise, I'm not terribly good at wording myself =P I would love md5 if I could use it, but what I really need is something built into javascript. Commented Oct 16, 2010 at 23:52
  • (Hmmm, JavaScript is a programming language, how would you use built-in stuff without writing some code yourself ;-) As for background POST: did you look at JSONP with jQuery?) Commented Oct 17, 2010 at 0:00
  • I rewrote the question in what is hopefully a less noisy and clearer way Commented Oct 17, 2010 at 0:00

3 Answers 3

2

encodeURIComponent, PHP will decode it automatically when populating $_POST or $_GET

Sign up to request clarification or add additional context in comments.

Comments

1
'&password='+encode(inputs[1].value)

Where's encode function coming from? Seems to me the quick answer to your question is using encodeURIComponent() instead, available since JavaScript 1.5. See also Comparing escape(), encodeURI(), and encodeURIComponent(); it does not encode everything either, but does encode all the server expects it to.

(As for cross-domain AJAX POST calls, I'd really have a look at "JSON with Padding". See JSONP with jQuery that I mentioned in the comments earlier. This will also prevent issues with the timeout you've randomly chosen, and jQuery will also help you, a lot, to get rid of inputs[0].value and the like. And, as you apparently already have a MD5 hash on the server, I'd really hash the password client side as well --see Karl's answer-- and compare those hashes instead. Respect your user's password and your own time, drop that no external libraries requirement!)

8 Comments

using escape, the # isn't a problem... it's just php's urldecode does not produce the exact input. There are a few corner cases (I wish I could remember where I read this) involving ' ', '+', and a few other characters
Oh, as you're not using <form>, I guess? Modern browsers also support encodeURI and the like, but I guess indeed escape should give you the same result as a plain <form>.
Oh, sorry. I'm trying to accomplish a cross-domain ajax request, and since this is forbidden the best solution I was able to think of is to try preload an "image" whose url is "server.com/remoteauth/?user=username&pass=password"
The trouble with jQuery is that it's an external library, and is quite large (compared to nothing, that is). I'm trying to keep the entire script under 25kb. Which makes including jQuery's 72kb minified version out of the question. However, encodeURIComponent() appears (from the doc and from testing) to accomplish my needs.
I'm also rewriting it to avoid that hardcoded timeout, because it's obviously a problem. Rather it'll wait for a little while and checking again, with a loop counter so that if that happens too often it sends the request again. Sometimes you just gotta get your hands dirty...
|
1

I don't think there's such a thing as a reversible hash function. There are plenty of javascript md5 libraries available, however.

1 Comment

apologies, I misspoke - in absence of md5 i'm looking for some kind of translation, i.e. base64 or something... basically something that'll make sure it gets passed to the script correctly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.