I have implemented Laravel 6 API and used Laravel's inbuilt Illuminate\Foundation\Auth\VerifiesEmails based on tutorial here but the email verification link is not expired and still accessible after successful email verification. I have found many tutorials regarding laravel frontend but how to implement it on API.
VerificationApiController
class VerificationApiController extends Controller
{
use VerifiesEmails;
/**
* Mark the authenticated user's email address as verified.
* #param Request $request
* #return JsonResponse
*/
public function verify(Request $request): JsonResponse
{
$userID = $request['id'];
$user = User::findOrFail($userID);
$date = date('Y-m-d g:i:s');
// to enable the “email_verified_at field of that
// user be a current time stamp by mimicking the
// must verify email feature
$user->email_verified_at = $date;
$user->save();
return response()->json('Email verified!');
}
/**
* Resend the email verification notification.
* #param Request $request
* #return JsonResponse|Response
*/
public function resend(Request $request)
{
if ($request->user()->hasVerifiedEmail()) {
return response()->json('User already have verified email!', 422);
}
$request->user()->sendEmailVerificationNotification();
return response()->json('The notification has been resubmitted');
// return back()->with(‘resent’, true);
}
}
User model
class User extends Authenticatable implements MustVerifyEmail
{
use HasApiTokens, Notifiable;
protected $fillable = [
'name', 'email', 'password'
];
/**
* The attributes that should be hidden for arrays.
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Send email verification notification
*/
public function sendApiEmailVerificationNotification()
{
$this->notify(new VerifyApiEmail); // my notification
}
}
Here are verification api routes
Route::get(‘email/verify/{id}’, ‘VerificationApiController#verify’)->name(‘verificationapi.verify’);
Route::get(‘email/resend’, ‘VerificationApiController#resend’)->name(‘verificationapi.resend’)
Here is UsersApiController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Illuminate\Support\Facades\Hash;
use Auth;
use Validator;
use Illuminate\Foundation\Auth\VerifiesEmails;
use Illuminate\Auth\Events\Verified;
class UsersApiController extends Controller
{
use VerifiesEmails;
public $successStatus = 200;
/**
* login api
*
* #return \Illuminate\Http\Response
*/
public function login(){
if(Auth::attempt([‘email’ => request(‘email’), ‘password’ => request(‘password’)])){
$user = Auth::user();
if($user->email_verified_at !== NULL){
$success[‘message’] = “Login successfull”;
return response()->json([‘success’ => $success], $this-> successStatus);
}else{
return response()->json([‘error’=>’Please Verify Email’], 401);
}
}
else{
return response()->json([‘error’=>’Unauthorised’], 401);
}
}
/**
* Register api
*
* #return \Illuminate\Http\Response
*/
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
‘name’ => ‘required’,
‘email’ => ‘required|email’,
‘password’ => ‘required’,
‘c_password’ => ‘required|same:password’,
]);
if ($validator->fails()) {
return response()->json([‘error’=>$validator->errors()], 401);
}
$input = $request->all();
$input[‘password’] = Hash::make($input[‘password’]);
$user = User::create($input);
$user->sendApiEmailVerificationNotification();
$success[‘message’] = ‘Please confirm yourself by clicking on verify user button sent to you on your email’;
return response()->json([‘success’=>$success], $this-> successStatus);
}
/**
* details api
*
* #return \Illuminate\Http\Response
*/
public function details()
{
$user = Auth::user();
return response()->json([‘success’ => $user], $this-> successStatus);
}
}
Here are user and auth routes
Route::post(‘login’, ‘UsersApiController#login’);
Route::post(‘register’, ‘UsersApiController#register’);
Route::group([‘middleware’ => ‘auth:api’], function(){
Route::post(‘details’, ‘UsersApiController#details’)->middleware(‘verified’);
}); // will work only when user has verified the email
so the problem is that when I click on verification link on email the user is verified but the link is not expired . I want the link to be expired as soon as user is verified. How to do that?
Have you implemented the VerifyApiEmail class?
namespace App\Notifications;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\URL;
use Illuminate\Auth\Notifications\VerifyEmail as VerifyEmailBase;
class VerifyApiEmail extends VerifyEmailBase
{
protected function verificationUrl($notifiable)
{
return URL::temporarySignedRoute(
'api.auth.verify', Carbon::now()->addMinutes(60), ['id' => $notifiable->getKey()]
);
}
}
Here you can add the expiration time in minutes, seconds or hours.
Please, I am totally new to Yii1.1, I am following a video tutorial and I have benn trying to follow up closely. I am trying to create and update the album model as indicated in the video tutorial. I typed everything the presenter typed: my codes are given below:
The AlbumController
class AlbumController extends Controller
{
/**
* #var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout='//layouts/column2';
/**
* #return array action filters
*/
public function filters()
{
return array(
'accessControl', // perform access control for CRUD operations
'postOnly + delete', // we only allow deletion via POST request
);
}
/**
* 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 authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update'),
'users'=>array('#'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'users'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
/**
* Displays a particular model.
* #param integer $id the ID of the model to be displayed
*/
public function actionView($id)
{
$this->render('view',array(
'model'=>$this->loadModel($id),
));
}
/**
* Creates a new model.
* If creation is successful, the browser will be redirected to the 'view' page.
*/
public function actionCreate()
{
$model=new Album;
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if(isset($_POST['Album']))
{
$model->attributes=$_POST['Album'];
if($model->save()){
//$this->redirect(array('view','id'=>$model->id));
Yii::app()->user->setFlash('saved', 'Data saved!');
$this->redirect(array('update','id'=>$model->id));
}
else{
Yii::app()->user->setFlash('failure', 'Data not saved!');
}
}
$this->render('create',array(
'model'=>$model,
));
}
/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id the ID of the model to be updated
*/
public function actionUpdate($id)
{
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if(isset($_POST['Album']))
{
$model->attributes=$_POST['Album'];
if($model->save()){
//$this->redirect(array('view','id'=>$model->id));
Yii::app()->user->setFlash('saved', "Data saved!");
$this->redirect(array('update','id'=>$model->id));
}else{
Yii::app()->user->setFlash('failure', "Data not saved!");
}
}
$this->render('update',array(
'model'=>$model,
));
/**
* Deletes a particular model.
* If deletion is successful, the browser will be redirected to the 'admin' page.
* #param integer $id the ID of the model to be deleted
*/
}
public function actionDelete($id)
{
$this->loadModel($id)->delete();
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
if(!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
}
/**
* Lists all models.
*/
public function actionIndex()
{
$dataProvider=new CActiveDataProvider('Album');
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
/**
* Manages all models.
*/
public function actionAdmin()
{
$model=new Album('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['Album']))
$model->attributes=$_GET['Album'];
$this->render('admin',array(
'model'=>$model,
));
}
/**
* Returns the data model based on the primary key given in the GET variable.
* If the data model is not found, an HTTP exception will be raised.
* #param integer $id the ID of the model to be loaded
* #return Album the loaded model
* #throws CHttpException
*/
public function loadModel($id)
{
$model=Album::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
/**
* Performs the AJAX validation.
* #param Album $model the model to be validated
*/
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='album-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
}
The Album model class
/**
* This is the model class for table "tbl_album".
*
* The followings are the available columns in table 'tbl_album':
* #property integer $id
* #property string $name
* #property string $tags
* #property integer $owner_id
* #property integer $shareable
* #property string $created_dt
*
* The followings are the available model relations:
* #property User $owner
* #property Photo[] $photos
*/
class Album extends CActiveRecord
{
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'tbl_album';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('owner_id, shareable, category_id', 'numerical', 'integerOnly'=>true),
array('name, tags', 'length', 'max'=>255),
array('description', 'length', 'max'=>1024),
array('description', 'match', 'pattern'=>'/[\w]+/u'),// \-\_\'\ \,\p{L}0-!
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('id, name, tags, owner_id, shareable, created_dt', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
//defined function beforeSave()..
protected function beforeSave(){
if(parent::beforeSave()){
if($this->isNewRecord){
$this->created_dt = new CDbExpression("NOW()");
$this->owner_id = Yii::app()->user->id;
}
return true;
}else
return false;
}
public function scopes(){
return array(
'shareable'=>array(
'order'=>'created_dt DESC',
'condition'=>'shareable=1',
)
);
}
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'owner' => array(self::BELONGS_TO, 'User', 'owner_id'),
'photos' => array(self::HAS_MANY, 'Photo', 'album_id'),
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'name' => 'Name',
'tags' => 'Tags',
'owner_id' => 'Owner',
'category_id'=>'Category',
'description'=>'Description',
'shareable' => 'Shareable',
'created_dt' => 'Created Dt',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
*
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
*
* #return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('name',$this->name,true);
$criteria->compare('tags',$this->tags,true);
$criteria->compare('description',$this->description);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* #param string $className active record class name.
* #return Album the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}
The Photo Model Class
/**
* This is the model class for table "tbl_photo".
*
* The followings are the available columns in table 'tbl_photo':
* #property integer $id
* #property integer $album_id
* #property string $filename
* #property string $caption
* #property string $alt_text
* #property string $tags
* #property integer $sort_order
* #property string $created_dt
* #property string $lastupdate_dt
*
* The followings are the available model relations:
* #property Comment[] $comments
* #property Album $album
*/
class Photo extends CActiveRecord
{
private $_uploads;
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'tbl_photo';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('album_id, sort_order', 'numerical', 'integerOnly'=>true),
array('filename', 'length', 'max'=>500),
array('tags', 'length', 'max'=>256),
array('caption, alt_text, created_dt, lastupdate_dt', 'safe'),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('id, album_id, filename, caption, alt_text, tags, sort_order, created_dt, lastupdate_dt', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'comments' => array(self::HAS_MANY, 'Comment', 'photo_id'),
'album' => array(self::BELONGS_TO, 'Album', 'album_id'),
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'album_id' => 'Album',
'filename' => 'Filename',
'caption' => 'Caption',
'alt_text' => 'Alt Text',
'tags' => 'Tags',
'sort_order' => 'Sort Order',
'created_dt' => 'Created Dt',
'lastupdate_dt' => 'Lastupdate Dt',
);
}
public function getImageParam(){
if(empty($this->_uploads)){
$this->_uploads = Yii::app()->params['uploads']. "/";
return $this->_uploads;
}
}
public function getUrl(){
return $this->getImageParam()."uploads/".CHtml::encode($this->filename);
}
public function getThumb(){
return $this->getImageParam()."thumbs/".CHtml::encode($this->filename);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
*
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
*
* #return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('album_id',$this->album_id);
$criteria->compare('filename',$this->filename,true);
$criteria->compare('caption',$this->caption,true);
$criteria->compare('alt_text',$this->alt_text,true);
$criteria->compare('tags',$this->tags,true);
$criteria->compare('sort_order',$this->sort_order);
$criteria->compare('created_dt',$this->created_dt,true);
$criteria->compare('lastupdate_dt',$this->lastupdate_dt,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* #param string $className active record class name.
* #return Photo the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}
The Photo Model
/**
* This is the model class for table "tbl_photo".
*
* The followings are the available columns in table 'tbl_photo':
* #property integer $id
* #property integer $album_id
* #property string $filename
* #property string $caption
* #property string $alt_text
* #property string $tags
* #property integer $sort_order
* #property string $created_dt
* #property string $lastupdate_dt
*
* The followings are the available model relations:
* #property Comment[] $comments
* #property Album $album
*/
class Photo extends CActiveRecord
{
private $_uploads;
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'tbl_photo';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('album_id, sort_order', 'numerical', 'integerOnly'=>true),
array('filename', 'length', 'max'=>500),
array('tags', 'length', 'max'=>256),
array('caption, alt_text, created_dt, lastupdate_dt', 'safe'),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('id, album_id, filename, caption, alt_text, tags, sort_order, created_dt, lastupdate_dt', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'comments' => array(self::HAS_MANY, 'Comment', 'photo_id'),
'album' => array(self::BELONGS_TO, 'Album', 'album_id'),
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'album_id' => 'Album',
'filename' => 'Filename',
'caption' => 'Caption',
'alt_text' => 'Alt Text',
'tags' => 'Tags',
'sort_order' => 'Sort Order',
'created_dt' => 'Created Dt',
'lastupdate_dt' => 'Lastupdate Dt',
);
}
public function getImageParam(){
if(empty($this->_uploads)){
$this->_uploads = Yii::app()->params['uploads']. "/";
return $this->_uploads;
}
}
public function getUrl(){
return $this->getImageParam()."uploads/".CHtml::encode($this->filename);
}
public function getThumb(){
return $this->getImageParam()."thumbs/".CHtml::encode($this->filename);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
*
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
*
* #return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('album_id',$this->album_id);
$criteria->compare('filename',$this->filename,true);
$criteria->compare('caption',$this->caption,true);
$criteria->compare('alt_text',$this->alt_text,true);
$criteria->compare('tags',$this->tags,true);
$criteria->compare('sort_order',$this->sort_order);
$criteria->compare('created_dt',$this->created_dt,true);
$criteria->compare('lastupdate_dt',$this->lastupdate_dt,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* #param string $className active record class name.
* #return Photo the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}
I am getting this error: CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (school2go2.tbl_album, CONSTRAINTtbl_album_ibfk_1FOREIGN KEY (owner_id) REFERENCEStbl_user(id) ON DELETE NO ACTION ON UPDATE NO ACTION). The SQL statement executed was: INSERT INTOtbl_album(name,tags,description,shareable,created_dt,owner_id) VALUES (:yp0, :yp1, :yp2, :yp3, NOW(), :yp4)
Please I am totally new to yii and even StackOverflow, pardon my inappropriate editing.I am still learning.
The error translates to: You are trying to insert an album without a corresponding owner.
Impossible to help more without knowing how you got that error.
I am new at Laravel and having some struggles with simple login and authorization pages.
I followed an awesome video tutorial by laracasts.com (credits for that one, really helpful).
My situation:
When implementing authorization to my page, the page after the login succeeds the authorization check.
So: loginform > press button > You are now logged in.
My problem:
After I press the back button and refresh, it still gives the login form. It shouldn't.
routes.php
<?php
Route::get('login', 'SessionsController#create');
Route::get('logout', 'SessionsController#destroy');
Route::resource('users', 'UsersController');
Route::resource('sessions', 'SessionsController');
Route::get('admin', function(){
return 'Admin page';
})->before('auth');
Route::get('dashboard', ['before' => 'auth', function(){
return 'Dashboard';
}]);
SessionsController.php:
<?php
class SessionsController extends BaseController{
public function create()
{
if ( Auth::check() )
{
Redirect::to('/admin');
}
return View::make('sessions.create');
}
public function store()
{
if( Auth::attempt(Input::only('email', 'password')) )
{
// if(Auth::check())
// {
// return 'check worked!';
// }
return 'Welcome ' . Auth::user()->username; //You are now logged in
}
return 'Failed';
}
public function destroy()
{
Auth::logout();
return Redirect::to('sessions.create');
}
}
User.php
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
public $timestamps = true;
protected $fillable = ['username', 'email', 'password'];
protected $guarded = ['id'];
public static $rules = [
'username' => 'required',
'password' => 'required'
];
public $errors;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
public function isValid()
{
$validation = Validator::make($this->attributes, static::$rules );
if($validation->passes() )
return true;
$this->errors = $validation->messages();
return false;
}
}
create.blade.php
#extends('layouts.default')
#section('content')
<h1>Create new user</h1>
{{Form::open([ 'route' => 'users.store' ]) }}
<div>
{{Form::label('username', 'Username: ')}}
{{Form::text('username')}}
{{$errors->first('username')}}
</div>
<div>
{{Form::label('password', 'Password: ')}}
{{Form::password('password')}}
{{$errors->first('password')}}
</div>
<div>
{{Form::submit('Create User')}}
</div>
{{Form::close() }}
#stop
So to speak: It never goes to the 'admin' route.
Your authentication code is correct and working. What you have is something going wrong in any other part of your Laravel application, web server or even PHP.
Since we are not seeing all your code, we can just guess, so my first one would be the Session not being stored correctly. Currently logged users are stored in Laravel Session. So, check your session driver, if it's in 'native', change it to 'database', but you'll have to create a sessions table, look at the docs. If you are already using 'database', change it back to 'native' or even 'file'.
Instead of run
return 'Welcome ' . Auth::user()->username; //You are now logged in
Please try
return Redirect::to('admin');
I need to override both authentication (for when user's trying to logging in) and also the function is being used to check if the user is logged in in the header of the application (the function that check the sessions and cookie to check if the user is logged in) but i don't know where are these methods? and also i don't know how to find where are these methods!
** The reason of ovveride is to also check a Flag, if the flag is FLASE don't authenticate the user, or even if the user is also authenticated on page change (header reload) log-out the user if the flag changed to FLASE**
It would be appreciated if you also helping me to find adequate references that can help me in similar situations beside yii/wiki and google i tried them :)
Regards,
For custom authentication extend CUserIdentity class:
app/components/UserIdentity.php
<?php
class UserIdentity extends CUserIdentity
{
const ERROR_USER_NOT_APPOVED=200;
private $_id;
/**
* Authenticates a user.
*
* #return boolean whether authentication succeeds.
*/
public function authenticate()
{
$criteria = new CDbCriteria;
$criteria->condition = 'LOWER(email.email)=LOWER(:email)';
$criteria->params = array(':email' => $this->username);
$member = Member::model()
->with('email')
->together()
->find($criteria);
if ($member === null) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
} elseif (!hash::check($this->password, $member->pass_hash)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} elseif (! $member->is_approved) {
$this->errorCode = self::ERROR_USER_NOT_APPOVED;
} else {
$this->_id = $member->id;
$this->username = $member->full_name;
$this->setState('email', $member->email->email);
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
/**
* #return integer the ID of the user record
*/
public function getId()
{
return $this->_id;
}
}
then create custom form (app/models/MainLoginForm.php):
<?php
/**
* MainLoginForm class.
* MainLoginForm is the data structure for keeping
* user login form data.
*/
class MainLoginForm extends CFormModel
{
public $email;
public $password;
public $rememberMe;
/**
* Declares the validation rules.
* The rules state that email and password are required,
* and password needs to be authenticated.
*/
public function rules()
{
return array(
array('email', 'filter', 'filter' => 'trim'),
array('email', 'required',
'message' => Yii::t('auth', 'Email address is required.')),
array('email', 'email',
'message' => Yii::t('auth', 'Enter a valid Email address.')),
array('password', 'required',
'message' => Yii::t('auth', 'Password is required.')),
// password needs to be authenticated
array('password', 'authenticate'),
array('rememberMe', 'safe'),
);
}
/**
* Declares attribute labels.
*/
public function attributeLabels()
{
return array(
'email' => Yii::t('auth', 'Email Address'),
'password' => Yii::t('auth', 'Password'),
'rememberMe' => Yii::t('auth', 'Remember me.'),
);
}
/**
* Authenticates the password.
* This is the 'authenticate' validator as declared in rules().
*/
public function authenticate($attribute, $params)
{
// we only want to authenticate when no input errors
if (! $this->hasErrors()) {
$identity = new UserIdentity($this->email, $this->password);
$identity->authenticate();
switch ($identity->errorCode) {
case UserIdentity::ERROR_NONE:
$duration = ($this->rememberMe)
? 3600*24*14 // 14 days
: 0; // login till the user closes the browser
Yii::app()->user->login($identity, $duration);
break;
default:
// UserIdentity::ERROR_USERNAME_INVALID
// UserIdentity::ERROR_PASSWORD_INVALID
// UserIdentity::ERROR_MEMBER_NOT_APPOVED
$this->addError('', Yii::t('auth',
'Incorrect username/password combination.'));
break;
}
}
}
}
and finally update your login method (actionLogin):
$form = new MainLoginForm;
if (isset($_POST['MainLoginForm'])) {
$form->attributes = $_POST['MainLoginForm'];
$valid = $form->validate();
if ($valid) {
// redirect
}
}
For auto logout you can extend CController:
app/components/MainBaseController.php
<?php
class MainBaseController extends CController
{
public $settings = array();
public function init()
{
parent::init();
// set global settings
// $this->settings = ...
if (YOUR_FLAG_VALIDATION AND !Yii::app()->user->isGuest) {
Yii::app()->user->logout();
}
}
}
and then use custom base controll:
class YourController extends MainBaseController
{
....
}
I am a newbie to yii. I have stuck my mind with yii-tutorials for creating roles in yii. but I am not getting how can I create role in yii. means I want to create two roles admin & staff and I want to give different priviliage to them.
I have created a role in user table, but I am not getting that how can I create a role and can assign priviliages to them, please help me guys
Thanks in advance
In your copenents/UserIdentity.php
class UserIdentity extends CUserIdentity{
private $_id;
public function authenticate()
{
$record=Members::model()->findByAttributes(array('username'=>trim($this->username)));
if($record===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else if($record->password!==md5(trim($this->password)))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->_id=$record->id;
$this->setState('username', $record->username);
$this->setState('name', $record->name);
$this->setState('type', $record->role);
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
public function setId($id)
{
$this->_id = $id;
}
}
You can create a new column name as "role". set the members type "admin" or "staff" to role column.
Be careful to that line.
$this->setState('type', $record->role);
Create a new helper file. /protected/helpers/RoleHelper.php
class RoleHelper {
public static function GetRole(){
if (Yii::app()->user->type == "admin"){
//set the actions which admin can access
$actionlist = "'index','view','create','update','admin','delete'";
}
elseif (Yii::app()->user->type = "staff"){
//set the actions which staff can access
$actionlist = "'index','view','create','update'";
}
else {
$actionlist = "'index','view'";
}
return $actionlist;
}
}
and in your controllers -> accessRules function
public function accessRules()
{
return array(
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array(RoleHelper::GetRole()),
'users'=>array('#'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
and dont forget to add 'application.helpers.*' to /config/main.php
'import'=>array(
'application.models.*',
'application.components.*',
'application.helpers.*',
),
This source is pretty good specially for beginners..I am using this method till now:
Simple RBAC in YII
Just follow the instructions given while having your desired modifications.
Concrete Example:
WebUser.php (/components/WebUser.php)
<?php
class WebUser extends CWebUser
{
/**
* Overrides a Yii method that is used for roles in controllers (accessRules).
*
* #param string $operation Name of the operation required (here, a role).
* #param mixed $params (opt) Parameters for this operation, usually the object to access.
* #return bool Permission granted?
*/
public function checkAccess($operation, $params=array())
{
if (empty($this->id)) {
// Not identified => no rights
return false;
}
$role = $this->getState("evalRoles");
if ($role === 'SuperAdmin') {
return 'SuperAdmin'; // admin role has access to everything
}
if ($role === 'Administrator') {
return 'Administrator'; // admin role has access to everything
}
if ($role === 'Professor') {
return 'Professor'; //Regular Teaching Professor, has limited access
}
// allow access if the operation request is the current user's role
return ($operation === $role);
}
}
Just connect it with your components/UserIdentity.php and config/main.php:
'components' => array(
// ...
'user' => array(
'class' => 'WebUser',
),
and thats it..
to check the role of the logged in:
Yii::app->checkAccess("roles");
where checkAccess is the name of your function in WebUser...
Please note that evalRoles is a column in your table that will supply the role of an account (on my link provided, that would be the word roles used in the major part snippet)