Search the Community
Showing results for tags 'social plugin'.
-
Hi Guys, So after reading multiple threads and searching for a solution required for a project, I decided to build a module to enable users to login to the CMS via their gmail account and hopefully the module can also be altered for LinkedIn and other Social accounts. Unfortunately the Facebook module does give you a Facebook ID and assigns the Facebook Role however I would like to assign the role, get the users email and create the user if its not in the system. I have basically taken the Facebook Login Module created by apeisa and manipulated the module to somewhat work with GMAIL. What it does now: It allows you to login but doesn't pull any data from GMAIL. Therefore it automatically logins in to the first account created in ProcessWire, but oddly changes the password, Im sure its due to the line of code in the module that is set to generate a random password via sha1. What I need it to do: If the user isn't in the system, get the gmail email, add the gmail email to the email field in ProcessWire, assign the gmail role or whatever role I want to auto assign it and log them in. My resources from Google: https://developers.google.com/accounts/docs/OAuth2 Please note, I will be updating the code as I make progress but please give input or help if you can. As always, thank you so much to everyone for their input and help, especially apeisa and craig a rodway for giving some direction initially. Here is what I have so far: <?php class GoogleLogin extends WireData implements Module, ConfigurableModule { const name = 'google-login'; //the google ID isn't used in Gmail so I am sure this will go away. const fieldName = 'google_id'; public static function getModuleInfo() { return array( "title" => "Google Login for Website", "version" => 001, "summary" => "Allows users to authenticate through their GMAIL account.", "autoload" => false ); } public function init() { } public function execute() { // Prevent association of Google Account to an existing user if ($this->user->isLoggedin()) { echo "Already logged in."; return; } $client_id = $this->googleAppId; $app_secret = $this->googleAppSecret; $redirect_uri = $this->page->httpUrl; $code = $_REQUEST["code"]; if(empty($code)) { $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection $dialog_url = "https://accounts.google.com/o/oauth2/auth?client_id=" . $client_id . "&redirect_uri=" . $redirect_uri . "&state=" . $_SESSION['state'] . "&scope=profile email&response_type=code"; echo("<script> top.location.href='" . $dialog_url . "'</script>"); } if($_SESSION['state'] && ($_SESSION['state'] === $_REQUEST['state'])) { $token_url = "https://accounts.google.com/o/oauth2/auth/access_token?" . "client_id=" . $client_id . "&redirect_uri=" . urlencode($redirect_uri) . "&client_secret=" . $app_secret . "&code=" . $code; $response = file_get_contents($token_url); $params = null; parse_str($response, $params); $access_url = "https://accounts.google.com/o/oauth2/auth/user?access_token=" . $params['access_token']; // Add stream context $options = array('http' => array('user_agent'=> $_SERVER['HTTP_USER_AGENT'])); $context = stream_context_create($options); $ghUserData = json_decode(file_get_contents($access_url, false, $context)); $this->processLogin($ghUserData); } else { echo("The state does not match. You may be a victim of CSRF."); } } public function processLogin($ghUserData) { $id = $ghUserData->id; $u = $this->users->get("google_id=$id"); // First we create random pass to use in login $uniqid = uniqid(); $pass = sha1($uniqid . $id . $ghUserData->updated_at); // User has logged in earlier with Google id, great news let's login if ($u->id) { $u->of(false); $u->pass = $pass; $u->addRole(self::name); $u->save(); } // User has not logged in before and autogenerate is on else if (!$this->disableAutogenerate) { $name = $this->sanitizer->pageName($ghUserData->name, true); $u = $this->users->get("name=$name"); // All seems to be fine, let's create the user $u = new User; $u->name = $name; $u->google_id = $ghUserData->id; $u->pass = $pass; $u->addRole(self::name); $u->save(); } else { echo $this->renderCreateUserForm(); } $this->session->login($u->name, $pass); $p = $this->pages->get($this->redirectPage); if (!$p->id) { $p = $this->pages->get(1); } $this->session->redirect($p->httpUrl); } public function renderCreateUserForm() { } static public function getModuleConfigInputfields(Array $data) { $fields = new InputfieldWrapper(); // since this is a static function, we can't use $this->modules, so get them from the global wire() function $modules = wire('modules'); $field = $modules->get("InputfieldText"); $field->attr('name', 'googleAppId'); $field->attr('value', $data['googleAppId']); $field->label = "Google App Id"; $field->description = 'Client Id for your project. You can create one from here: https://console.developers.google.com'; $fields->add($field); $field = $modules->get("InputfieldText"); $field->attr('name', 'googleAppSecret'); $field->attr('value', $data['googleAppSecret']); $field->label = "Google App Secret"; $field->description = 'Client Secret for your project. Available in your project console here: https://console.developers.google.com'; $fields->add($field); /* $field = $modules->get("InputfieldCheckbox"); $field->attr('name', 'disableAutogenerate'); $field->attr('value', 1); $field->attr('checked', empty($data['disableAutogenerate']) ? '' : 'checked'); $field->label = "Don't set username automatically, but let the user choose username when doing the first login"; $fields->add($field); */ $field = $modules->get("InputfieldPageListSelect"); $field->attr('name', 'redirectPage'); $field->attr('value', $data['redirectPage']); $field->label = "Page where user is redirected after succesful login"; $fields->add($field); return $fields; } public function install() { $name = self::name; $fieldName = self::fieldName; $page = $this->pages->get("/$name/"); if($page->id) throw new WireException("There is already a page installed called '/$name/'"); $template = $this->templates->get($name); if($template) throw new WireException("There is already a template installed called '$name'"); $fieldgroup = $this->fieldgroups->get($name); if($fieldgroup) throw new WireException("There is already a fieldgroup installed called '$name'"); $field = $this->fields->get($fieldName); if($field) throw new WireException("There is already a field installed called '$fieldName'"); $role = $this->roles->get($name); if (!$role->id) { $this->roles->add($name); $this->message("Create role called $name"); } $fieldgroup = new Fieldgroup(); $fieldgroup->name = $name; $title = $this->fields->get('title'); if($title) $fieldgroup->add($title); $fieldgroup->save(); $template = new Template(); $template->name = $name; $template->fieldgroup = $fieldgroup; $template->allowPageNum = 1; $template->save(); $this->message("Installed template $name"); $page = new Page(); $page->template = $template; $page->parent = '/'; $page->name = $name; $page->title = "Google Login"; $page->addStatus(Page::statusHidden); $page->save(); $this->message("Installed page $page->path"); $basename = $name . ".php"; $src = $this->config->paths->SessionGoogleLogin . $basename; $dst = $this->config->paths->templates . $basename; if(@copy($src, $dst)) { $this->message("Installed template file $basename"); } else { $this->error("Templates directory is not writable so we were unable to auto-install the $basename template file."); $this->error("To complete the installation please copy $basename from $src to $dst"); } // Create hidden inputfield $input = new InputfieldText; $input->set('collapsed', Inputfield::collapsedHidden); // Create field called Google and set details and inputfield $f = new Field(); $f->type = $this->modules->get("FieldtypeText"); $f->name = $fieldName; $f->label = 'Google ID'; $f->description = 'Stores Google id for user'; $f->inputfield = $input; $f->save(); // Add the field to user fieldgroup (basically means user template in this context) $fg = $this->fieldgroups->get('user'); $fg->add($f); $fg->save(); } public function uninstall() { } }
- 4 replies
-
- 4
-
- module development
- login module
-
(and 1 more)
Tagged with:
-
I don't always want to bother registering users, I just want them to be able to log in. I'm not alone because there are a number of other threads about OAuth, none of which mentions Opauth. Opauth is a lean, non-opinionated, modular PHP thingy. It has 18 providers listed on their page, some of which are built-in, some are 3rd-party. Their website itself is an example, and it's on github as well. It's lean: it doesn't need the provider SDKs, it implements only what it needs in the auth modules. It's non-opinionated: you give your user a link to /auth/facebook, and then you are waiting for the results on /auth/callback; what you do with the returned array is your choice (the urls are of course customizable). I could put together Twitter / Google / Facebook auth for a (non-processwire) site really quick. I stored the API auth params for the modules in a table as json-encoded hashes (just 2 keys and 2 values, but the keys vary by API, so that was the easiest), and I did the same with the returned credentials. Besides provider, uid, and credentials (what we really need), Opauth also returns a somewhat variable set of details about the profiles in the info key, stuff like name, gender, urls, and the like; the Processwire module could opt to mine and store in fields whatever it deems useful, then store the rest as json, or just throw it away. An example for what you get in your callback: Array ( [auth] => Array ( [provider] => Facebook [uid] => 1480000000008166 [info] => Array ( [name] => Tibs [image] => https://graph.facebook.com/1480000000008166/picture?type=square [first_name] => Tibs [urls] => Array ( [facebook] => https://www.facebook.com/app_scoped_user_id/1480000000008166/ ) ) [credentials] => Array ( [token] => CAAEajKBojCkBAHj6cy0mM4EZBPvs082t5Vkm3PGa44jsfrfzCS1SwV09qOaZBQYnfxLnCacb7Wkr536wDzusIh4mkMmvwoC5VdZBKFRAGyLpqcVJYdWCIFv0iwfkjpiLpDsGVBChj1ac1Lq6ZBFjuCdrtfpcQtgWbonDVCzwGwZB0A37vLaQbCuh8OnbdRY1U1dPE2ZBU2PmgNGNP1ghzNo [expires] => 2016-01-06T10:29:53+00:00 ) [raw] => Array ( [id] => 1480000000008166 [first_name] => Tibs [gender] => male [link] => https://www.facebook.com/app_scoped_user_id/148000000000166/ [locale] => en_US [name] => Tibs [timezone] => 1 [updated_time] => 2015-01-25T19:54:12+0000 [verified] => 1 ) ) [timestamp] => 2015-11-07T11:20:56+00:00 [signature] => hmcuwumqat4w84g1gkw0cgokloogg4w ) To be honest, I'm not even working on anything in Processwire at the moment, but I wanted to post about Opauth since I discovered it. If someone decides to implement OAuth before I get around it myself, Opauth is the perfect candidate to do the heavy lifting