CakePHP Salvare la data del login ad ogni autenticazione.
Se volete salvare la data del login dei vostri utenti, dovet disabilitare l'autoRedirect nel vostro app_controller. Senza questo piccolo accorgimento, il codice all'interno della funzione login() viene ignorato.
function beforeFilter() {
....
$this->Auth->autoRedirect = false;
....
}
function login() {
if($this->Auth->user()){
$this->loginDate();
//reindirizzamento dopo un corretto login
$this->redirect(array('controller' => 'users', 'action' => 'view'));
}
}
function loginDate() {
$this->User->id = $this->Session->read('Auth.User.id');
$now = date("Y-m-d H:i:s");
$this->User->saveField('last_login', $now);
}
come integrare twitter@anywhere nell’autenticazione di cakePHP
Twitter @anywhere è l'API di twitter che vi permette di integrare la funzionalità di twitter nel vostro sito con poco codice javascript.
Registrare la vostra application, richiedere le API e cominciare ad usarle sul vostro sito è una cosa che si fa velocemente e che non spiego qui.
La cosa che mi interessa è l'integrazione di twitter anywhere nella mia application...ovvero:
Come faccio a far si che se un utente si logga su twitter viene registrato nel mio database ed automaticamente loggato?
Dovrò gestire l'output di twitter anywhere e tramite ajax passarlo ad un handler nel nostro controller che loggherà l'utente in caso sia andato tutto bene, restituirà un errore in caso contrario.
Per prima cosa includiamo questi 2 file js nell'header del nostro template.
echo $html->script("jquery.js");
echo $html->script("checkTwitterUsername.js");
Jquery,js lo trovate sul sito di jquery, lo script checkTwitterUsername.js è una funzione che prende l'output di twitter@anywhere e lo passa all'handler ajax che si occuperà di loggare l'utente.
/*place a <div id = "reply"></div> if you want to check te response */
function checkTwitterUsername (twitterusername) {
if (twitterusername == undefined) {
alert('twitterusername not setted');
}else{
$.ajax({
type : "POST",
url : "/users/handleTwitterUser",
data : {name : twitterusername},
success : function (response) {
$("#reply").append(response);
window.location.reload();
},
error : function (response) {
$("#reply").append(response);
}
});
}
}
includiamo anche l'element twitter_login.ctp, che fa uso di twitter @anywhere, che trovate qui sotto
<? echo $this->element("twitter_login")?>
twitter_login.ctp
<?php
$id = 'twitter-login-button-'.rand(1000,9999);
echo '<span id="'.$id.'"></span>';
echo $html->scriptBlock("
twttr.anywhere(function (T) {
var currentUser,
screenName,
profileImage,
profileImageTag;
if (T.isConnected()) {
currentUser = T.currentUser;
screenName = currentUser.data('screen_name');
profileImage = currentUser.data('profile_image_url');
profileImageTag = \"<img src='\" + profileImage + \"'/>\";
$('#{$id}').append(\"Logged in as \" + profileImageTag + \" \" + screenName );
$('#signout').bind(\"click\", function () {
twttr.anywhere.signOut();
window.location.reload();
});
} else {
T('#{$id}').connectButton();
T.bind(\"authComplete\", function () {
if (T.isConnected()) {
currentUser = T.currentUser;
screenName = currentUser.data('screen_name');
checkTwitterUsername(screenName);
}
});
};
});
");
?>
Nella vostra tabelle Users aggiungete un campo twitter_username, nel controller users aggiungete questo metodo
/**
* It's called by checkTwitterUsername.js
* Once a user is logged in twitter:
* 1)if it's not logged in your application and there is no twitter_username as the twitter user logged,
* create and log the user in your application.
* If a user with the same twittername exists, log the user.
* 2)If the user is logged, check if he has a twitter_username, if not, update the value "twitter username"
*
* @return string
* @access public
**/
function handleTwitterUser(){
$this->autoRender = false;
$msg = "";
if(!empty($_POST['name'])){
$name = $_POST['name'];
if(!$this->Auth->user()){
$user = $this->User->findByTwitterUsername($name);
if(!$user){
//generate passowrd
srand ((double) microtime( )*1000000);
$random_number = rand(0,10);
$user['username'] = $name;
$user['twitter_username'] = $name;
$user['password'] = $this->Auth->password($random_number);
$user['is_active'] = 1;
$user['is_verified'] = 1;
$this->User->create();
$this->User->save($user);
$msg = "User saved and ";
}
$this->Auth->login($user);
if($this->Session->check('Auth.User')) {
App::import('Model', 'User');
$User = new User;
$User->store($this->Session->read('Auth'));
$User->store(array('User' => array('is_loggedin' => true)));
}
$msg.= "User logged";
return $msg;
}else{
$user = $this->User->findByTwitterUsername($name);
if(!$user){
$this->User->id = User::get('User.id');
$this->data['User']['twitter_username']=$name;
$this->User->store(array('User' => array('twitter_username' => $name)));
$this->User->save($this->data);
$msg = "your twitter username is now associated with yours profile";
return $msg;
}
}
}else{
$error = "Error, we could not associate your twitter username with your profile";
return $error;
}
}
In questa porzione di codice faccio uso di "$User = new User;" per salvare e recuperare in ogni parte della mia applicazione informazioni relative all'utente. Questa tecnica è spiegata bene, con esempi pratici nel libro gratis scaricabile online http://www.pseudocoder.com/free-cakephp-book/
Per poter sloggare l'utente automaticaente sia da twitter che dalla vostra applicazione, dovete far si che il link a logout abbia l'id "signout".
echo $this->Html->link('logout', array('controller' => 'users', 'action' => 'logout' ),
array('id'=>'signout')
);