zf2 How to get user details with AuthenticationService - php

I've created a module to authenticate a user. Now, after login I go to the index action and the system tells me that the authentication is all working fine. But What I want is to print some more user details from the Users table. When I try:
print_r($this->getServiceLocator()->get('AuthService')->getAdapter()->getResultRowObject());
I get no result. What am I doing wrong?
Thanks for your help.
In my module.php I've the following code(snippet):
public function getServiceConfig()
{
return array(
'abstract_factories' => array(),
'aliases' => array(),
'factories' => array(
// Some more code here but removed for simplicity
// Autentication
'AuthService' => function ($sm) {
$adapter = $sm->get('master_db');
$dbAuthAdapter = new DbAuthAdapter ( $adapter, 'Users', 'email', 'password' );
$auth = new AuthenticationService();
$auth->setAdapter ( $dbAuthAdapter );
return $auth;
},
// Some more code here but removed for simplicity
}
In my IndexController.php I've the following (snippets):
public function indexAction()
{
if(!$this->getServiceLocator()->get('AuthService')->hasIdentity()){
return $this->redirect()->toUrl('login');
}
echo "hello, it works!";
exit;
}
public function loginAction(){
$form = $this->getServiceLocator()->get('LoginForm');
$viewModel = new ViewModel(array('form' =>
$form));
return $viewModel;
}
public function processAction(){
// Lots of code here
if($bcrypt->verify($loginData['password'], $userData->password))
{
$this->getAuthService()
->getAdapter()
->setIdentity($loginData['email'])
->setCredential($userData->password);
$result = $this->getAuthService()->authenticate();
}
// Lots of code here where I check if $result->isValid and route to the
// correct action
}
public function getAuthService() {
if(!isset($this->authservice)) {
$this->authservice = $this->getServiceLocator()->get('AuthService');
}
return $this->authservice;
}

Instead of refering to the authentication result object (which properly only exists in the authentication request) you can simply store user details in the authentication identity (#see http://framework.zend.com/manual/2.1/en/modules/zend.authentication.intro.html).
For your case you could also store user specific details right after the validation of the authentication result in the authentication storage:
if ($result->isValid()) {
//authentication success
$resultRow = $this->authService->getAdapter()->getResultRowObject();
$this->authService->getStorage()->write(array(
'id' => $resultRow->id,
'user_agent' => $request->getServer('HTTP_USER_AGENT'))
);
}
(This information was taken from this authentication tutorial http://samsonasik.wordpress.com/2013/05/29/zend-framework-2-working-with-authenticationservice-and-db-session-save-handler/)

Related

Laravel 5 Redirect from a sub-method

I'm using Socialite to get user information from facebook. All is going well but my redirect isn't working
Sub-routes
I read that it's not possible to do a redirect from a submethod, or
any method that's not in your routes.
But how else can i redirect the user after I logged them in?
My URL looks like this after the successfull facebook handshake
http://tmdb.app/auth/login/facebook?code=AQBTKNZIxbfdBruAJBqZ8xx9Qnz...
Code
class SocialController extends Controller {
public function login(Authenticate $authenticate, Request $request)
{
return $authenticate->execute($request->has('code'), $this);
}
public function userHasLoggedIn($data)
{
$user = User::where('provider_id', $data->id)->first();
if( !$user )
{
$user = User::create([
'name' => $data->name,
'email' => $data->email,
'provider' => 'facebook',
'provider_id' => $data->id
]);
}
// NOT WORKING!
return redirect('test');
}
}
Your login function should be handling the redirect.
I'm guessing execute returns $data if the user is sucessfully logged in and false if not.
class SocialController extends Controller {
public function login(Authenticate $authenticate, Request $request)
{
if($data = $authenticate->execute($request->has('code'), $this))
{
$user = User::where('provider_id', $data->id)->first();
// maybe delegate the user creation to another class/service?
if( !$user )
{
$user = User::create([
'name' => $data->name,
'email' => $data->email,
'provider' => 'facebook',
'provider_id' => $data->id
]);
}
return redirect('test');
}
return redirect('fail_view');
}
}
You can do it using PHP header function in Laravel sub method. I try it and works properly. Hope it can help you.
// You can using the following code
$url= url("about-laravel");
header("Location:" . $url);
exit;
// Or using the following code to redirect and keep set flash message
$result= $this->yourMethod(); // return redirect($this->route)->with('flash_message', 'I\'m Flash Message'); for TRUE or NULL for false
if( $result ){
return $result;
}

Laravel 4.2 session::get() method not returning session data in controllers

Hi help me,
login code
public function store()
{
$credentials = array(
'u_email' => Input::get('email'),
'password' => Input::get('password'));
if (Auth::attempt($credentials) ) {
$user = Auth::user()->toArray();
$userrole = with(new User)->get_user_role($user['u_id']);
$userobj['u_id'] = $user['u_id'];
$userobj['u_shortcode'] = $user['u_shortcode'];
$userobj['utype'] = $user['utype'];
$userobj['u_title'] = $user['u_title'];
$userobj['u_fname'] = $user['u_fname'];
$userobj['u_lname'] = $user['u_lname'];
$userobj['u_email'] = $user['u_email'];
$userobj['u_role'] = $userrole;
$userobj['id'] = Session::getId();
Session::put('admin', $userobj);
$value = Session::get('admin');
return Response::json([
'user' => $userobj ],
202
);
}else{
return Response::json([
'flash2' => 'Authentication failed'],
202
);
}
}
and my second controller is:
public function get_sessionobj()
{
var_dump(Session::all());
$value = Session::get('admin');
print_r($value);
exit();
}
when i am calling second controller after login then session data not printed. in login controller Session::get('admin') function returning data. and i am using file driver for session storage. I have seen my session file there was some data like this:
a:5:{s:6:"_token";s:40:"XrUgs7QLPlXvjvyzFaTdmDpqGL0aSZRzkJS0il9f";s:38:"login_82e5d2c56bdd0811318f0cf078b78bfc";s:1:"1";s:5:"admin";a:9:{s:4:"u_id";s:1:"1";s:11:"u_shortcode";s:5:"u1001";s:5:"utype";s:1:"1";s:7:"u_title";s:3:"Mr.";s:7:"u_fname";s:6:"Aristo";s:7:"u_lname";s:5:"Singh";s:7:"u_email";s:24:"chandan.singh#jetwave.in";s:6:"u_role";a:3:{i:0;s:1:"1";i:1;s:1:"2";i:2;s:1:"3";}s:2:"id";s:40:"cd074f7f61fcc88b3d92c482e57e8a12dc888958";}s:9:"_sf2_meta";a:3:{s:1:"u";i:1410525787;s:1:"c";i:1410525787;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}
Call a function get_sessionobj() in store function
Example:
public function store(){
$this->get_sessionobj();
}

Forms in Yii: how to send data back, if verification has failed

I got this code:
public function actionJoin() {
$user = new RUser;
if (isset($_POST['RUser']))
$user->attributes = $_POST['RUser'];
$this->render('join',
array(
'user' => $user
)
);
}
Which will not yet allow user to register. What I want to know is how to send data back to user. I mean, if user form haven't passed verification I have to send some data back, so there is no need for user to re-enter it again.
I can do so with this:
$user->mail = $_POST['RUser']['mail'];
But it's looks like dropping back to plain PHP and not using powers of the framework here.
Addition. Publishing RUser class, if needed:
class RUser extends CFormModel
{
public $mail;
public $alias;
public function safeAttributes()
{
return array(
'mail', 'alias'
);
}
}
Which version of Yii you use.
In Yii 1.1, there are no safeAttributes. You use the followings,
public function rules()
{
return array(
array('mail, alias', 'safe'),
);
}

Retreving specific row from database in yii

I am working on a job site,And want to show only the jobs posted by a particular user in cgridview.My actuall aim is to authenticate the user so that only jobs posted by him/her will be visible in cgridview.I have done the following stuff,but not working.
In controller:
public function actionViewJob() {
$user_id = Yii::app()->session['user_id'];
/* For User Authentication */
if (Yii::app()->user->getId() === null)
$this->redirect(array('site/login'));
/* For User Authentication */
/* Have tried the following codes to filter */
$model= ViewJob::model()->findAll(array(
'select'=>'*',"condition"=>"user_id='$user_id'",
));
// $model=ViewJob::model()->findByAttributes(array('user_id'=>Yii::app()->user->id));
// $model = ViewJob::model()->findAll("user_id=$user_id");
$model = new Viewjob('search');
$params = array('model' => $model,
);
$this->render('viewjob', $params);
}
In view
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' =>$model->search()
// 'filter' => $model, /* not using this option ,so commented it */
))
In model
// Do I really Need This Function //
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('user_id', $this->user_id, true);
return new CActiveDataProvider('viewjob', array(
'criteria'=>$criteria,
));
},,
What am I doing wrong here.It is still fetching all the available rows in table.
You define $model 3 times:
$model= ViewJob::model()->findAll(array(
'select'=>'*',"condition"=>"user_id='$user_id'",
));
Then
$model = new Viewjob('search');
And
'dataProvider' =>$model->search()
Choose one that you need, better last. And add to controller
$model->user_id = $user_id
It will works.
Create new CDbCriteria object and add condition using it and pass it to model.
In Controller:
public function actionViewJob() {
$criteria = new CDbCriteria ();
$criteria->condition = 'user_id=' . Yii::app()->user->id;
$model = ViewJob::model()->findAll($criteria);
$params = array('model' => $model);
$this->render('viewjob', $params);
}
And in View, simply:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider' =>$model
Also for use Authentication, in your controller you don't need to check, if user has the user id, simply add access rules, which will automatically redirect user to the login page to view the job and once they are logged-in, will return them to the same page. So, add this at the top of our controller..
class YourController extends Controller {
public function filters() {
return array(
'accessControl', // perform access control
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* #return array access control rules
*/
public function accessRules() {
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions' => array('index', 'view'),
'users' => array('*'),
),
array('allow', // allow authenticate user actions
'actions' => array('viewjob'),
'users' => array('#'),
),
array('deny', // deny all users
'users' => array('*'),
),
);
}

CakePHP 2.1 Adding fields to login page

I have made a a basic login form with three fields, they're "company", "employee", and "password" I tried using the default Auth component:
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
}
but as this parses the default "username", and "password" fields I can't log in. How can I change the Auth function to validate my three fields and log me in?
Sorry if this is a noob question, I had a read through http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html but nothing on there helped.
Try the following:
public function beforeFilter() {
$this->Auth->authenticate = array(
'Form' => array(
'fields' => array(
'username' => 'employee',
),
),
);
}
public function login() {
if ($this->request->is('post')) {
$this->Auth->authenticate['Form']['scope'] = array(
'User.company_id' => $this->request->data['User']['company_id'],
// or however this condition needs to be setup as
);
if ($this->Auth->login()) {
// login success
} else {
// login fail
}
}
}
Basically, add the third condition as a scope.

Categories