PDA

View Full Version : Social Security Number verification by javascript and web service



web.dev.2k14
04-07-2014, 04:05 AM
As part of my project, I am required to provide my client a functionality that can verify user's input Social Security Number by using CBSV's web service. I've read the documents in CBSV's website, including Consent Based Social Security Number Verification Service (CBSV) | Web Services (http://www.ssa.gov/cbsv/webservice.html), but can't see any example of using jQuery and AJAX. Anyway, here's what I've done so far.


function checkSSN(ssnfield,fnamefield,lnamefield,dobfield)
{
var ssn = $("#"+ssnfield).val();
var first_name = $("#"+fnamefield).val();
var last_name = $("#"+lnamefield).val();
var middle_name = get_Middle_name(first_name, last_name);
var date_of_birth = $("#"+dobfield).val().replace("/", "");
var age = getAge($("#"+dobfield).val());
var minor = (age >= 16)?"N":"Y";


$.ajax
({
url: "https://ws.ssa.gov/CBSVWS/services/CBSVServices?wsdl",
type: "POST",
dataType: "xml",
data: {"ssn":ssn, "firstName":first_name, "middleName":middle_name, "lastName":last_name, "dateOfBirth":date_of_birth, "minor":minor},
contentType: "text/xml; charset=\"utf-8\"",
success: function (data) {
console.log("Success:");
},
error: function (xhr, st, er) {
console.log("Request error:" + er);
}
});
}


function getAge(dateString)
{
var today = new Date();
var birthDate = new Date(dateString);
var age = today.getFullYear() - birthDate.getFullYear();
var m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate()))
{
age--;
}
return age;
}


function get_Middle_name(fname,lname)
{
if ((typeof fname == 'string' || fname instanceof String) && (typeof lname == 'string' || lname instanceof String))
{
fname = fname.replace(/\s+/, "");
lname = lname.replace(/\s+/, "");
var middle_name = "";
var full_name = fname + " " + lname;
var count_words = countWords(full_name);
if(count_words >= 3)
{
var array_of_names = full_name.split(" ");
for(var i=1; i < array_of_names.length - 1 ; i++)
{
middle_name += array_of_names[i];
}
}
else
{
middle_name = "";
}
return middle_name;
}
else
return "";
}


function countWords(s){
s = s.replace(/(^\s*)|(\s*$)/gi,"");//exclude start and end white-space
s = s.replace(/[ ]{2,}/gi," ");//2 or more space to 1
s = s.replace(/\n /,"\n"); // exclude newline with a start spacing
return s.split(' ').length;
}


function _webSSNVerification_forSignUp()
{
checkSSN("personalInfo_personalSSN", "personalInfo_personalFName", "personalInfo_personalLName", "personalInfo_personalBirthday");
}


In the php file that contains the form, I have this piece of jquery code to register event of the SSN textbox after user enters value in it.


$("#personalInfo_personalSSN").each(function(){
this.addEventListener("blur", _webSSNVerification_forSignUp, true);
});



And these are the messages that I got in the console.log


OPTIONS ws.ssa.gov/CBSVWS/services/CBSVServices?wsdl 500 (Error) jquery-1.7.2.min.js:4
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost'; is therefore not allowed access. jquery-1.7.2.min.js:4
send jquery-1.7.2.min.js:4
f.extend.ajax jquery-1.7.2.min.js:4
checkSSN common.js:519
_armSSNVerification_forSignUp common.js:584


My question is, what did I do wrong? How can I call the CBSV webservice to check user's input SSN?

Please help. Thank you.

jscheuer1
04-07-2014, 06:01 AM
You cannot do this on a page not on the https://ws.ssa.gov domain (same origin policy for AJAX calls):



$.ajax
({
url: "https://ws.ssa.gov/CBSVWS/services/CBSVServices?wsdl",

You can write a PHP script to post to that page and host that on your domain and then make an AJAX post call to that script on your server. But it's a bit complicated. I'm no expert at this, but I have done something like it once. It requires either curl or other advanced PHP techniques to retrieve the data from the remote page that your local PHP script is posting to. I used PHP 5.3.0 and curl.

Essentially, you use jQuery ajax to post to the local PHP script, which posts to the remote page and returns what that page returns to it to jQuery ajax.

What I would do is make sure PHP is enabled on the server and that it has curl enabled. This can be tricky, or not. It might already be enabled. If it is not, you may have to use Google to determine what all the configuration settings in php.ini are required to enable it. Then make a file - call it getcbsv.php and put it in the same folder as your page, here's the code I would try:


<?php
foreach ($_REQUEST as $key => $val){
$postarray[] = $key . '=' . $val;
}
$postdata = implode('&', $postarray);
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://ws.ssa.gov/CBSVWS/services/CBSVServices?wsdl");
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$data = curl_exec($ch);
curl_close($ch);
echo $data;
?>

Then, on your page, where you have:


$.ajax
({
url: "https://ws.ssa.gov/CBSVWS/services/CBSVServices?wsdl",
type: "POST",
dataType: "xml",
data: {"ssn":ssn, "firstN . . .

Make that:


$.ajax
({
url: "getcbsv.php",
type: "POST",
dataType: "xml",
data: {"ssn":ssn, "firstN . . .

Assuming everything has been properly enabled, and I've made no error in the PHP/curl code, and the csbv service allows it, that should do it.

The alternative would be to use the cbsv service as intended, which I'm guessing involves posting directly to their page and having a return page on your domain.

web.dev.2k14
04-07-2014, 06:49 AM
Thanks John for your solution. I think it is a very good one. However, I'm not sure if I can apply to my case. I'm sorry I forgot to say that I'm developing this app based on a Symfony app that's already built. This app uses twig templates for creating design for each php page. The code that controls process this signup process is in another section (the Controller) of the app. That is a big problem. I'm trying to figure out where to put curl PHP code. Should it be in the twig file or in the Controller php file?

Is there any other solution (like an equivalence of curl in javascript) for this case? Please help.

web.dev.2k14
04-07-2014, 09:20 AM
thanks. I've finally managed to add the code above to the Controller that process the SignUp feature and it seems to work, except now it throws this error message to my face.


SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

I wonder what does that mean and how can I solve it? Please help. Thanks.

jscheuer1
04-07-2014, 02:06 PM
I'm not certain what that means. However, my best guess is that since the data on ss is on a secure server (https) aka Secure Socket Layer (SSL), it requires that your requesting page (getcbsv.php in my example) also reside on an https partition or folder.

It might not be that - you should look over the documentation of the ws.ssa.gov service you're using or ask them to be sure.

There are two ways around this if in fact it is what the message you are getting means:


Instead of requesting:


curl_setopt($ch, CURLOPT_URL, "https://ws.ssa.gov/CBSVWS/services/CBSVServices?wsdl");

Use:


curl_setopt($ch, CURLOPT_URL, "http://ws.ssa.gov/CBSVWS/services/CBSVServices?wsdl");

That will only work if the data you want from ws.ssa.gov is also on an insecure partition - It probably isn't, but it's worth a try.


Establish an SSL on your server or use an existing SSL on your server to host the getcbsv.php file. If your server doesn't have an existing SSL (either a shared https folder/domain, or the option to use the https protocol outright on the domain itself), the cheapest way is to contact the host and have them give you access to a shared one (this is a little tricky to work with, as it's like adding another domain - everything relating to your page that uses getcbsv.php will need to be on this domain. Alternatively, you can get one that is not shared. That's more expensive, but if you're doing a lot of commerce, makes more sense and is easier to deal with. Then it's all one domain and you only need to have content that requires the SSL to have the https protocol.