I am using Codeigniter and including Facebook library to implement Facebook authentication. I am autoloading the library as:
$autoload['libraries'] = array('database', 'session', 'facebook_lib', 'aescryption');
And the facebook_lib.php library is calling facebook.php (which in turn calls base_facebook.php). Now, this is making the site very slow. It takes around 4-8 seconds to load pages on my localhost. I didn't knew this earlier. The pages were loading really slow. I then profiled the application and found that even if I am just calling a blank page it was really slow. I then thought that something else is going on and my first thought was the autoload configs. If I remove the 'facebook_lib' library then the page loads right away.
Any ideas what can be done here? Has anyone encountered a similar problem?
Thanks.
UPDATE:
Here is the code that I have in facebook library:
$this->ci =& get_instance();
// Create our Application instance
//(replace this with your appId and secret).
$this->ci->load->file(APPPATH.'/third_party/facebook.php');
$this->data['facebook'] = new Facebook(array(
'appId' => $this->ci->config->item('fb_app_id'),
'secret' => $this->ci->config->item('fb_secret_key')));
$this->data['fb_user'] = $this->data['facebook']->getUser();
if ($this->data['fb_user']) {
try {
$this->data['$user_profile']=$this->data['facebook']->api('/me');
$this->ci->load->model('login_signup_model');
$this->ci->login_signup_model->storeFBUser($this->data['$user_profile']['id']);
return true;
} catch (FacebookApiException $e){
error_log($e);
$this->data['fb_user']=null;
}
}
Related
I am experimenting with Drupal 8 as our customer websites. Our customers authenticate through our own authentication application at the moment which speaks to our document store (instead of MySQL) to authenticate a user and provide them with a unique session ID (JWT eventually but that's another day and conversation) which we can use to then query a REST API and get user data in any of our other self apps.
We are moving over from an old JSP based websites to drupal as our apps are now written in Symfony 3 but want our customer websites to be Drupal 8.
Here's the bit I am trying to work out. If I authenticate in our old website I want to be able to redirect to the Drupal 8 website with the session ID we have in our hand and use that to fetch a object back of our logged in user. I have this bit working fine but I now am in a position to say... Ok I have the user object back, the 3rd party service has said that session ID is valid so we know we are authenticated.
Please refer to the below flow chart. I want to be able to also authenticate in Drupal 8 manually. Is this possible (I am sure it is) and if so can someone point me in the right direction as to what I need/should be doing, API's I should be calling?
Thank you kindly and good day :)
You should use the External Auth module.
A good exemple of how use this module is the SimpleSamlPHP Auth
Ok so it turned out not to be that tricky in the end. I thought I would have to extend and implement various class and create my own provider (which is probably the best practice) but for KISS sake I found another way.
Create a user first if one does not exists based on the user data I get back from my external service. Then pass that created user to the user_login_finalize method (why are a lot of methods underscored Drupal...) which then authenticated my user.
public function inbound(Request $request)
{
// Point the guzzle client to our external session service.
$client = new GuzzleHttpClient([
'base_uri' => 'https://myexternalservice.com/apps/authentication/2/',
]);
// Attempt to send to request with the session ID from the parameters.
try {
$response = $client->request('GET', 'api/v1/user/' . $request->get('session_id'));
} catch (\Exception $e) {
throw new \HttpException($e->getMessage());
}
// Convert the response to an array.
$result = json_decode((string) $response->getBody(), true);
// Convert our array to a user entity.
if ($user = $this->convertResponseToUser($result['user'])) {
try {
// Attempt to load the user. If the user does not exist then create them first.
if (!$assumeUser = user_load_by_mail($user->getEmail())) {
// Create a Drupal user object.
$assumeUser = $this->createUser([
'name' => $user->getFirstName() . ' ' . $user->getLastName(),
'mail' => $user->getEmail()
]);
$assumeUser->save();
}
// Authenticate the user.
user_login_finalize($assumeUser);
} catch (\Exception $e) {
drupal_set_message(t('An unhandled exception occurred during authentication.'), 'error');
return $this->redirect('user.login');
}
}
return $this->redirect('mymodule.route');
}
I'm pretty new to the Zend framework, and am attempting to integrate an SSO with an existing Zend site. I have installed SimpleSamlPHP and can connect to the ADFS server and get assertion data in the form of First Name and Last Name using the following script
$lib = "/var/simplesamlphp";
$sp = "wte-sp";
try {
if(!file_exists("{$lib}/_autoload.php")) {
throw(new Exception("simpleSAMLphp lib loader file does not exist: ".
"{$lib}/_autoload.php"));
}
include_once("{$lib}/_autoload.php");
$as = new SimpleSAML_Auth_Simple($sp);
$as->requireAuth();
$valid_saml_session = $as->isAuthenticated();
} catch (Exception $e) {
throw(new Exception("SSO authentication failed: ". $e->getMessage()));
return;
}
if (!$valid_saml_session) {
try {
$as = new SimpleSAML_Auth_Simple($sp);
$as->requireAuth();
} catch (Exception $e) {
throw(new Exception("SSO authentication failed: ". $e->getMessage()));
return;
}
}
$attributes = $as->getAttributes();
print_r($attributes);
I am now attempting to move this into a Zend controller, on page load I am redirected to the SSO page for authentication and returned to the correct page with no problems, however, it appears as if the $attributes array is empty. I have confirmed that I have got the SAML cookie set, and I am seeing SAML data when I var_dump($_SESSION); but it looks as if somewhere along the line Zend is doing something unknown to the data as I'm always hitting the if (!$valid_saml_session) { statement and getting stuck in an authentication redirect loop.
As mentioned before, the code works perfectly as a standalone page, but not being too clued up on Zend, I'm drawing a bit of a blank. I have changed the last lines to
$attributes = $as->getAttributes();
$this->view->attributes = $attributes;
And have sent the results to the view, but the array is empty.
I am able to get the Login and Logout URLs to the view with no problems.
EDIT - 21/12/15
Looks like this is related to the way Zend is setting up sessions. In my Bootstrap.php file I have
protected function _initSession()
{
Zend_Session::setOptions(array(
'save_path' => $this->options['resources']['session']['save_path'],
'use_only_cookies' => 'on',
'remember_me_seconds' => 86400
));
Zend_Session::start();
}
If I comment this out, I get the SSO information back with no problems. I'm concerned about making this change as I'm not sure of the implications across the application, does anyone have a better solution to stop Zend from trashing my SSO session data?
I'm creating a project which uses CakePHP framework, and the PHP OAuth module.
The reason I'm using the module over a Vendor plugin is because the APIs need to have data/custom headers sent to them or else they generate 500s, and I know the standard PHP module does this well.
The issue is that when I use OAuth->fetch("http://www.example.com" ...), CakePHP redirects the external fetch request to my localhost (which I'm developing on), thus resulting in no data being generated.
It looks like the only way I can get external data is by using CakePHP's HTTPSocket class, but that doesn't allow me to send that data I need to send to the OAuth provider.
Does anyone know how to turn off this routing, or if I should be doing something differently?
UPDATE : Currently code is as follows:
public function createClient() {
$client = new OAuth(
'key',
'secret'
);
$client->disableSSLChecks();
if ($accessToken = $this->getAccessToken() !== false) {
$client->setToken(
$accessToken[$this->accessTokenKeyKeyname],
$accessToken[$this->accessTokenSecretKeyname]
);
}
return $client;
}
$url = 'http://example.com';
$client = $this->createClient();
$client->fetch($url, null, OAUTH_HTTP_METHOD_GET);
The request/access tokens are generated successfully, but the fetch continues to redirect to localhost, instead of example.com (example.com being used as an example URL).
I am using PHP5 and CodeIgniter and I am trying to implement a single-sign on feature with facebook (although I don't think that facebook is relevant to the question). I am somewhat of a novice with PHP and definitely one with CodeIgniter, so if you think my approach is just completely off telling me that would be helpful too.
So here is in short what I am doing:
//Controller 1
$this->load->plugin("facebook");
$facebook = new Facebook(array (
'appId' => $fbconfig['appid'],
'secret' => $fbconfig['secret'],
'cookie' => true,
)
);
$fbsession = $facebook->getSession(); //works fine
$this->session->set_userdata('facebook', serialize($facebook);
Now I would like to grab that facebook object in a different controller.
//Controller 2
$facebook = unserialize($this->session->userdata('facebook'));
$fbsession = $facebook->getSession();
Produces the error: Call to undefined method getSession. So I look up more about serialization and think that maybe it just doesn't know what the facebook object's attributes are.
So I add in a
$this->load->plugin('facebook');
To controller 2 as well and I get a "Cannot redeclare class facebook." I am strongly suspecting that I am misunderstanding sessions here. Do I have to somehow tell PHP what kind of object it is? Thanks for the help.
Turns out I made a very stupid beginner mistake. My second controller was named Facebook! That's a little embarrassing....
Can anyone post simple step by step integration for openid into a site which has a login system already?
I decided to use PHP OpenID 2.1.3 but could get where to start and what to do.
I think your best bet is using the OpenID module from the Zend Framework. It can be used on it's own, without having to use the whole framework, and they have a fairly simple explanation on how to use it on their manual pages. It's as simple (if you understand the concept of OpenID) as:
login_page.php:
// Load the library Zend Framework way, or load it yourself...
// Always good to pick apart the library anyway, to see how it works:
Zend_Loader::loadClass('Zend_OpenId');
$consumer = new Zend_OpenId_Consumer();
if(!$consumer->login($_POST['openid_identifier'], 'redirect_to.php'))
{
die('OpenID login failed.');
}
redirect_to.php:
Zend_Loader::loadClass('Zend_OpenId');
$consumer = new Zend_OpenId_Consumer();
if($consumer->verify($_GET, $id))
{
echo htmlspecialchars($id).' is a valid ID.';
}
else
{
// redirect to "login.php?login=failed".
if(!headers_sent())
{
header('HTTP/1.1 307 Temporary Redirect', true, 307);
header('Location: login.php?login=failed');
}
else die('Invalid ID.');
}
It is a lot easier to use than the PHP OpenID Library (php-openid) provided by the OpenID Foundation.
EDIT: How to implement Zend_OpenId (in response to comment).
Download the latest Zend Framework, and extract the folder ZendFramework-1.9.2/library/Zend/OpenId.
There are however a few things you have to do:
Change the class extends value in [...]/OpenId/Exception.php from Zend_Exception to Exception.
Go through every file (tedious, I know) and replace all the require's and include's to absolute path names.
Now you can reference the classes by:
require_once '/path/to/OpenId/Consumer.php';
$consumer = new Zend_OpenId_Consumer();
// If you plan on making your own OpenID's, use 'Provider' instead of 'Comsumer'.
require_once '/path/to/OpenId/Provider.php';
$provider = new Zend_OpenId_Provider();
Now, the best advice I can give you though is to read through the manuals! Don't expect it to work first time... Zend's implementation may be easier, but that doesn't stop OpenID being a pain in the ass!
No, there is no simple guide. There are too many login systems and different implementations to make this simple and straightforward.
For particular scripts, try googling it. For any other scripts, you will have to integrate OpenID into your application. If you use MVC, you're in luck: Have a look at the user model and plug OpenID into it.