📜 ⬆️ ⬇️

Authorization through VKontakte, Mail.ru and others for the most beginners - 2

In the last part, we looked at authorization through VKontakte, today we’ll stop at mail.ru and use avatars from both social networks.
To begin with, as always, we need to register our application in the social network (in Mile, there is a clear separation between applications and websites, but I’m out of habit to say “application”). By the way, during the registration process you will see from three to five js errors, someday mail.ru will fix them. After registration, you have access to the application ID, private key (nothing private, used for js-api calls, visible to everyone) and secret key (used for server-server interaction, do not tell anyone and do not forget in the comments).
On the application settings page, we see another interesting parameter “Address of the page receiver.html”. If it does not aim to find out what it is for, then the only thing that we learn from the reference:
For site API to work correctly, you need to place the receiver.html file on your domain.

If you do not plan to use the JS API, then you do not need this file. We will place a button on the authorization / registration page. The PR department of Mile strictly forbids changing anything in the logo, so we use it in the strict form it is provided to us.

The link on the picture will be either this:
connect.mail.ru/oauth/authorize?client_id=APP_ID&response_type=token&redirect_uri=_REDIRECT_URI&host=http://HOST.com

where you need to specify your application number, your domain in the host parameter and the URI for redirection in the redirect_uri parameter.
The second option is to make an intermediate page using the JS API, below the native example of Mail with one-space killing indents.
<script type= "text/javascript" src= "http://cdn.connect.mail.ru/js/loader.js" ></script>
<script type= "text/javascript" >

mailru.loader.require( 'api' , function () {
mailru.connect.init( '_APP_ID_' , '__PRIVATE_KEY__' );
mailru.events.listen(mailru.connect.events.login, function (session){
window.location.reload();
});
mailru.events.listen(mailru.connect.events.logout, function (){
window.location.reload();
});
mailru.connect.getLoginStatus( function (result) {
if (result.is_app_user != 1) {
mailru.connect.initButton();
} else {
mailru.common.users.getInfo( function (result){console.log(result[0].uid)});
location.href= '/mail.login.php' ;
}
});
});

</script>
<a class = "mrc__connectButton" >@mail.ru</a>


* This source code was highlighted with Source Code Highlighter .

Why might need the second option? As life has shown, if a user clicks on a link from the first option and goes to a page with a username and password (if he is not authorized in Mile at the moment), then at least in the https address line, and the mail.ru domain, but panic and think that they are trying to steal his login and password. It is not clear why, but if you show these fields in a pop-up window (apparently more familiar and more commonly used), then there are fewer panicked users.
So, regardless of which option we have chosen, in any case, as a result, the user will be transferred to the page mail.login.php or another one you specified. In case of successful authorization of the user on the mail.ru side on your domain, he creates a cookie called mrc, which can be parsed as follows:
parse_str(urldecode($_COOKIE['mrc']),$array);
And here it turns out not very pleasant moments: for the signature / verification of the signature, the API uses the md5 comparison (a list of all request parameters sorted alphabetically without the & signs) and the sig parameter from the mail.ru cookie. Therefore, we need two small functions offered to us by the Mile team:
function sign_client_server(array $request_params, $uid, $private_key) {
ksort($request_params);
$ params = '' ;
foreach ($request_params as $key => $value) {
$ params .= "$key=$value" ;
}
return md5($uid . $ params . $private_key);
}

function sign_server_server(array $request_params, $secret_key) {
ksort($request_params);
$ params = '' ;
foreach ($request_params as $key => $value) {
if ($key!= 'sig' ) {
$ params .= "$key=$value" ;
}
}
return md5($ params . $secret_key);
}


* This source code was highlighted with Source Code Highlighter .

I have slightly corrected the sign_server_server function by adding a check that the key of the array element is not equal to 'sig'. This is done in order to avoid deleting an element from an array or copying an array to another for verification before each check.
To begin with, let's check whether the answer came from the social network (in the $ array array we have information from a mailrush cookie):
if (sign_server_server($array,$secretkey)==$array[ 'sig' ]) {

What is surprising if we used the “native” function to verify the signature without removing the sig element from the array, the comparison would return false. Since the initial information from Mile is rather scarce (only identifiers and the expiration of the user's session on Mile, which we don’t actually need), we need to get the name, surname and credit card number using the users.getInfo method. This is done like this:
//
$ params = array(
"method" => "users.getInfo" ,
"app_id" => "640345" ,
"session_key" =>$array[ 'session_key' ],
"uids" =>$array[ 'vid' ],
"secure" => "1"
);

$url = "http://www.appsmail.ru/platform/api?" .http_build_query($ params ). "&sig=" .sign_server_server($ params ,$secretkey);
$response = json_decode(file_get_contents($url));


* This source code was highlighted with Source Code Highlighter .

There is no need to reinvent the bicycle in order to form a request, there is a built-in function http_build_query. $ response returns us an array of user objects (in our case there is 1 element in the array), from which we get the first name, last name, nickname, identifier and avatar. We do this before querying the database, because in any case, we will need this data (we will update the first name, last name and avatar).
After we received the data from the social network, it's time to work on our side. Taking criticism and a little abstracting from the type of database used:
$stmt = $dbh->prepare( "SELECT id FROM tracker_users WHERE username = :username" );
$stmt->bindParam( ":username" , "mm-{$array[' vid ']}" , PDO::PARAM_STR, 23);
$stmt->execute();


For users from the social network MoiMir, I decided to select logins like “mm-20 numbers”. Yes, it is precisely the 20-digit number as an idish, for parking, do not make the conversion to a normal integer. After that, if the user is already in our database, we simply update his data, create our cookies for him and transfer to the main page, if not, then we will create an entry in the table and perform actions from the previous item.
if ($stmt ->fetchColumn() > 0) {
//
} else {
//
}


No one has any interest in the full presentation of all requests and trifles, as it turned out from the previous article, so we’ll stop at the next stage of integration - avatars from social networks. A small picture (ideally for display near comments) is in $ response [0] -> pic_small, and the VKontakte avatar from the previous article can be obtained from the GET parameters $ _GET ['photo_rec']. It should be noted that Mailovsky avatars have a size of 45 by 45, while from VKontakte it is 50 by 50. I am glad that both options are square and can be reduced to the same size. If you want to bring to 50 to 50, then from the mail it is better to take the increased avatar 90 by 90.

')

Source: https://habr.com/ru/post/126872/


All Articles