📜 ⬆️ ⬇️

Through authorization on your website via Twitter

Gone are the days when each forum on the personal page of each Vasisualiya Sverdyshchenko required separate registration.
We gradually get used to the fact that you can leave a comment on behalf of your OpenID / OAuth provider virtually everywhere. Also, plug-ins through Twitter / Facebook / Google / Yandex / Vkontakte have been written for all popular CMS long ago. In addition, there is DISQUS ... But what if we want to give the user of a third-party service any additional powers without forcing him to create a separate account on our website? Especially if for our CMS there is no miracle plug-in yet?
I will tell you how to quickly and painlessly screw through authorization to an exotic CMS and what are the underwater rakes along the way.

Xaraya + Twitter


')

Ingredients


For example, I will choose Twitter authorization in CMS Xaraya . The choice of provider due to its popularity. CMS is exactly this - for three reasons: I like it, it is little known (and, as a result, it differs little from a self-written one) and, finally, it is well-designed (what does it have to be - it will become clear a little later).
The MVC Xaraya architecture is such that all elements of each page are context sensitive. Each module may be able (and perhaps not able to) to display both the main content (for example: blog posts, separate blog posts) and so-called. “Blocks” that are usually embedded in side columns and displayed next to any other content generated by other modules. However, that I crucify here - so almost all CMS are arranged. I will only make a reservation that in the code below there are some functions specific to Xaraya - they all start with the prefix “ xar ” and by the name it is always clear what they do. It should not affect the understanding of the mechanism.
Our module will not display any "main" content. It will consist of one block, in which there will be either a button (the user is not logged in):
Sign in with Twitter
or a business card user login:
mudasobwa: logged in

Recipe


We want to provide the following behavior:

The main problem is that OAuth implies double redirection to a third-party site (authorization provider site, in our case, twitter.com ). Therefore, from the block of our CMS, it is not easy to execute it - after hiking for tokens and authorization - the context of the current session will be lost. So, it is necessary to be perverted with pop-up windows (I know, I know that it is ugly, but what to do ...).

Cooking method


My CMS can show different block patterns for simple wanderers and users by login.
Let's start with the simplest - let's make a block template for wanderers. It will have only one button, and a little script:
 <img src="/modules/authtwitter/xarimages/darker.png" alt="Sign in with Twitter" style="cursor:pointer;" onclick="popUp('#$url#');" id="loginBtn"/> 

The popUp function, oddly enough, will open a pop-up window in which we will go through a thorny way of authorization. I borrowed the authorization code itself from Abraham Williams , it is on the Twitter API Wiki . Our first level looks like this:
  require_once(dirname(__FILE__) . '/../libs/twitteroauth/twitteroauth.php'); require_once(dirname(__FILE__) . '/../libs/twitteroauth/config.php'); /* Build TwitterOAuth object with client credentials. */ $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); /* Get temporary credentials. */ $request_token = $connection->getRequestToken(OAUTH_CALLBACK); /* Save temporary credentials to session. */ /* NB! The code below is specific to Xaraya! */ xarSessionSetVar('oauth_token', $request_token['oauth_token']); xarSessionSetVar('oauth_token_secret', $request_token['oauth_token_secret']); /* NB! End of specific to Xaraya codepiece. */ /* If last connection failed don't display authorization link. */ switch ($connection->http_code) { case 200: /* Build authorize URL and redirect user to Twitter. */ $url = $connection->getAuthorizeURL($request_token); header('Location: ' . $url); // ⇐ That's why we needed a popup window break; default: /* Immediately return if something went wrong. */ return USER_AUTH_FAILED; } 

Twitter stores authorization tokens for each application (and our CMS is an application for them) forever, so if a user has ever registered on our website, the chain of transitions will not require user input. If this is the first attempt to login to us - Twitter will ask the standard Allow / Deny. And if the user is not logged in on Twitter - he will first be asked to log in. After all this, if the user has clicked “Allow”, we will receive a reverse redirect to the address that we passed to getRequestToken . Here's how to process it:
  require_once(dirname(__FILE__) . '/../libs/twitteroauth/twitteroauth.php'); require_once(dirname(__FILE__) . '/../libs/twitteroauth/config.php'); /* If the oauth_token is old—redirect to the connect page. */ if ( isset($_REQUEST['oauth_token']) && xarSessionGetVar('oauth_token') !== $_REQUEST['oauth_token'] ) { xarSessionSetVar('oauth_status', 'oldtoken'); xarRedirectUrl('…'); } /* Create TwitteroAuth object with app key/secret and token key/secret from default phase */ $connection = new TwitterOAuth( CONSUMER_KEY, CONSUMER_SECRET, xarSessionGetVar('oauth_token'), xarSessionGetVar('oauth_token_secret') ); /* Request access tokens from twitter */ $access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']); /* If HTTP response is 200 continue otherwise send to connect page to retry */ switch ($connection->http_code) { case 200: // http://apiwiki.twitter.com/w/page/22554689/Twitter-REST-API-Method%3A-account%C2%A0verify_credentials $content = $connection->get('account/verify_credentials'); default: xarRedirectUrl('…'); } 

Now we have a treasure - the user data that Twitter gave us. It's time to return them to our application:
 if(window.opener != null && !window.opener.closed) { window.opener.setCredentials(<?php echo json_encode($content); ?>); } 

Yeah. Now it's time to tinker with your own authorization system.

Sparrows, come to us


So, our unit received user data. First things first - close the annoying pop-up window. Then, fill in the pseudo-form (or rather, the hidden form) with the received data and let us go to check whether this user is familiar to us, or we still have to register it in our database:
 function setCredentials(content) { if (popUpObj) { popUpObj.close(); popUpObj = null; } if (content && content.screen_name) { document.getElementById("name").value = content.name; document.getElementById("screenname").value = content.screen_name; document.getElementById("profileimageurl").value = content.profile_image_url; document.getElementById("url").value = content.url; document.getElementById("statustext").value = content.status.text; document.getElementById("description").value = content.description; document.getElementById("profiletextcolor").value = content.profile_text_color; document.getElementById("profilelinkcolor").value = content.profile_link_color; document.getElementById("profilebordercolor").value = content.profile_sidebar_border_color; document.getElementById("doAuthForm").submit(); } } 

We need all this data to draw the user's business card with his favorite colors. The form, as you understand, was prepared in advance in plain HTML. This is where submit will go:
  extract($args); $user_info = array( 'pass' => $pass, 'screenname' => $screenname, 'name' => $name, 'statustext' => $statustext, 'profileimageurl' => $profileimageurl, 'url' => $url, 'description' => $description, 'profiletextcolor' => $profiletextcolor, 'profilelinkcolor' => $profilelinkcolor, 'profilebordercolor' => $profilebordercolor ); // Check, if the user already exists in our database $userRole = xarGetRole(array('uname' => $user_info['screenname'])); if (!$userRole) { $userRole = xarCreateRole( array( 'uname' => $user_info['screenname'], 'realname' => $user_info['name'], 'email' => '', // Bloody Twitter does not provide emails 'pass' => $user_info['pass'], 'date' => time(), 'authmodule' => 'authtwitter' ) ); } /* Now we are to store user credentials so that when CMS will * proceed with user registration and switch block to * the template for logged in user, we could draw the card */ xarSessionSetVar('user_info', $user_info); 


We are waiting for guests


Now we just have to prepare for the fact that CMS wants to change the template of our block to another option: for the user to login. I was too lazy to format this code in a human way, anyway, we have already worked out all the logic. Judge strictly :-)
  <div id="twCredentials" class="twcredentials"> <img id="twPhoto" class="twphoto" src="#$user_info['profileimageurl']#"/> <span class="twlogout cuprum"> <a href="&xar-modurl-authsystem-user-logout;"> <xar:mlstring>Logout</xar:mlstring> </a> </span> <img id="twServiceLogo" class="twservicelogo" src="/i/twitbird.png" /> <span id="twScreenName" class="twscreenname cuprum"> <a href="http://twitter.com/#$user_info['screenname']#"> #$user_info['screenname']# </a> </span> <br/> <span id="twName" class="twname ubuntu"> <xar:if condition="empty($user_info['url'])"> #$user_info['name']# <xar:else /> <a href="#$user_info['url']#">#$user_info['name']#</a> </xar:if> </span> <div class="twdescription ubuntu"> <span id="twDescription"> <xar:if condition="empty($user_info['statustext'])"> #$user_info['description']# <xar:else /> #$user_info['statustext']# </xar:if> </span> </div> </div> 

I repeat, now we have to see something like this:
mudasobwa: logged in

More recipes


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


All Articles