YII2 - check user - php

Okay, so, i am trying to write an API, and for the login function, you send the phone and password and if they match with a record in the database, we send back the user object.
You send phone and password via GET request, and I know what that means security wise, so don't mention that in solution.
Here is code for the API controller
<?php
namespace api\modules\v1\controllers;
use yii\rest\Controller;
use yii\data\SqlDataProvider;
use yii\web\Response;
use yii;
use common\models\User;
class UserController extends ApiController{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;
public $phone;
public $password;
private $_user = false;
private $password_hash;
public function actionIndex(){
if(isset($_GET['phone']) && isset($_GET['password']))
{
$this->phone = $_GET['phone'];
$this->password = $_GET['password'];
if(!is_null($this->getUser($this->phone)))
{
//if the user is there, we try and validate the password
if (Yii::$app->getSecurity()->validatePassword($this->password, $this->_user->password_hash))
{
echo ("good password");
return $this->_user;
} else
{
echo('bad password');
}
}else
{
return['User Not Found, Please Check Your Credentials And Try Again'];
}
}
else
{
if(!isset($_GET['phone']))
{
return array('Please provide your phone number');
}
if(!isset($_GET['password']))
{
return array('Please provide your password');
}
}
}
public function getUser($phone)
{
if ($this->_user === false) {
$this->_user = User::findOne(['phone' => $phone,'status' => self::STATUS_ACTIVE ]);
}
return $this->_user;
}
}
According to this section of the documentation, the validatePassword() should work, but even when i send the right password, it doesn't work.

Related

How to build login system in Codeigniter 4?

I want to build a login system using Codeigniter 4.
But I face some error.
I have some data in Users_model;
Here is my some codes:
Controller/Signin.php
<?php
namespace App\Controllers;
use App\models\Users_model;
class Signin extends BaseController {
public function index() {
return view('signin/index');
}
public function authenticate() {
if ($this->exists($_POST['email'], $_POST['password']) != NULL) {
$session = session();
$session->set('email', $_POST['email']);
return $this->response->redirect(site_url('signin/profile'));
} else {
$data['msg'] = 'wrong';
return view('signin', $data);
}
}
public function profile() {
return view('signin/profile');
}
private function exists($email, $password) {
$model = new Users_model();
$account = $model->where('email', $email)->first();
if ($account != NULL) {
if (password_verify($password, $account['password'])) {
return $account;
}
}
return NULL;
}
}
Models/Users_model.php
<?php
namespace App\models;
use CodeIgniter\Model;
class Users_model extends Model {
protected $table = 'users';
protected $primaryKey = 'id';
protected $allowedFields = ['first_name', 'last_name', 'email', 'password'];
}
But I face this error:
Please help me.
Or please someone suggest me a login system in another way in Codeigniter 4?
If you want to make login system, I suggest you to use validation to make user is valid and redirect to another controller or view. Then you can use filter to check that user is logged in or not and adding some routes filter to protect other controller.
First read this Codeigniter 4.0.4 documentation https://codeigniter4.github.io/userguide/libraries/validation.html
You could search anything you need there.
return view('signin', $data);
for
return view('signin/index', $data);

Laravel - can't get auth::atempt to work properly

$inputs["mail"] = Input::get('mail');
$password = Hash::make(Input::get("password",""));
$user = new User();
$user->password=$password;
$inputs["password"] = $password;
if( Auth::attempt($inputs) )
{
return 'loginOK';
}
else
{
return 'false';
}
i think that $password is different from password of database.
Do I need to try to other way?
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface,
RemindableInterface {
protected $table ='users';
public function getAuthIdentifier(){
return $this->getKey();
}
public function getRememberToken(){
return $this->remember_token;
}
public function getAuthPassword(){
return $this->password;
}
public function setRememberToken($value){
$this->remember_token = $value;
}
public function getRememberTokenName(){
return 'remember_token';
}
public function getReminderEmail() {
return $this->email;
}
}
it is User model.
can't get auth::atempt to work properly
what problem is it?
 
$input = [
'mail' => Input::get('mail'),
'password' => Input::get('password'),
 ];
 if (Auth::attempt($input)) {
echo 'Success';
 } else {
echo 'Failed';
 }
I edited by folower.
I have som trouble.
still i cant get
The problem is that you are passing the Hashed password to the attempt method, that method actually expect the unhashed password and does the hashing itself, so doing:
$inputs["password"] = Input::get('password');
should do the trick.
I'm not sure if your playing around but your code is not properly written and you should consider using the Input object directly.
Two things:
You don't need to hash the password
You don't need to make a user model.
It is enough to do something as follows:
$input = [
'mail' => Input::get('mail'),
'password' => Input::get('password'),
];
if (Auth::attempt($input)) {
echo 'Success';
} else {
echo 'Failed';
}

how to remember a user who is login

I have created a sign in form with a remember me checkbox. I want to know how can i allow user to keep sign in when the browser is closed or sign out person when they close the browser. A sample code would be nice thank you.
here is my code
class HomeController extends BaseController {
public function getIndex()
{
if(Auth::check())
{
return Redirect::to('profile');
}
return View::make('index');
}
public function postRegister()
{
//gets array of the register form input values
$value = Input::all();
// create a new instance of the User model
$user = new User;
$validate = $user->userValidate($value);
//checks if the validation for the field fails
if($validate->fails())
{
/* $message = $validation->messages();
return $message; */
return Redirect::back()->withInput()->withErrors($validate);
}
//adds the users input to speicific field in the users table
$user->user_name = $value['username'];
$user->email = $value['email'];
$user->password = Hash::make($value['password']);
//save the inputs to the users table
$user->save();
return 'information has been stored';
}
public function getRegister()
{
$title = 'Register';
return View::make('register')->with('title',$title);
}
public function getSignIn()
{
$title = 'Signup';
return View::make('signup')->with('title',$title);
}
public function postSignIn()
{
//user's information
$credentials = array('email' => Input::get('email'),'password'=>Input::get('password'));
//logs this user in and checked if they are registered already in
if(Auth::attempt($credentials,false))
{
return Redirect::to('profile');
}
return Redirect::back()->withInput();
}
}
You just have to turn it on in your login method:
if (Auth::attempt(array('email' => $email, 'password' => $password), true))
{
// The user will now be logged in and remembered
}
else
{
// Raise a login error
}
This "true" parameter is to remember your user.
Here is the Laravel Auth::attempt() method declaration:
public function attempt(array $credentials = array(), $remember = false, $login = true)
{
...
}
You could set a cookie on the users browser (make sure you tell them if you are) to identify them. But beware that this could be modified by a malicious user.
PHP Cookies Documentation

Yii Authentication error: After login successfull Yii::app()->user->isGuest() always return true

I started creating a difference between the authenticated users and guest user. But always when i identify the user and it get the login successfully, it still returns true when i make use Yii::app()->user->isGuest. Here is the code which i am using:
if (Yii::app()->user->isGuest){
echo 'Welcome back Guest';
} else {
echo 'Welcome back '.Yii::app()->user->name;
}
I always get the 'welcome back guest', whether i have logged in (successfully) or not. And if i have logged in again i got this message. and here is the User Identify code.
class UserIdentity extends CUserIdentity {
/**
* Authenticates a user.
*/
private $_id;
public function authenticate() {
$user = Users::model()->findByAttributes(array('username' => $this->username));
if ($user === null)
$this->errorCode = self::ERROR_USERNAME_INVALID;
else if ($user->password !== $this->password)
$this->errorCode = self::ERROR_PASSWORD_INVALID;
else {
$this->_id = $user->id;
$this->setState('title', $this->username);
$this->setState('id', $user->id);
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId() {
return $this->_id;
}
}
Please help me to get rid of this problem.
You should fix LoginForm
/**
* 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;
}
}
}
class UsersController extends Controller
{
/**
* Displays the login page
*/
public function actionLogin()
{
$model = new LoginForm;
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
$valid = $model->validate();
if ($valid) {
$this->redirect(Yii::app()->user->returnUrl);
}
}
$this->render('login', array('model' => $model));
}
}
Can you show your config?
Answer can be found here yii authentication error
You can also read more on yii authentication here authentication and authorisation
Try this and see using Not(!) operator
if (!Yii::app()->user->isGuest){
echo 'Welcome back Guest';
} else {
echo 'Welcome back '.Yii::app()->user->name;
}
You should NOT do this :
$this->setState('id', $user[0]->id);
setState should not be used for the 'id'. For returning the 'id' you have already overridden the getId() method.
If you do need to set it, change it something like this :
$this->_id = $user[0]->id;
Hope this helped.
Regards,

REST api authenication with laravel

I am building a RESTful api with laravel using the RESTful controller property. So far i've been able to get most of it working. The issue am having now is authenication, am trying to use Amazon approach using a "user_id" and "signature".
Am creating the signature using php's 'hash_hmac()'.
this an example api controller
class Api_Tasks_Controller extends Api_Controller {
public $restful = true;
public function get_index($id = null) {
$this->verfiy_request();
if(!is_null($id))
{
return Response::json(array("tasks"=>"just one"),200);
}
else
{
return Response::json(array("tasks"=>"everthing"),200);
}
}
}
and this the api controller class
class Api_Controller extends Controller {
public function verify_request() {
//user id
$user_id = (int) Input::get('user_id');
//signature
$sig = Input::get('sig');
//Lookup user
$user = Sentry::user($user_id);
if($user) {
//user email
$email = $user->email;
//user api key
$api_key = $user->metadata['api_key'];
//recreate signature
$_sig = hash_hmac("sha256",$email.$user_id,$api_key);
if($_sig === $sig) {
return Response::json(array("message"=>"Request Ok"),200);
}
else {
return Response::json(array("message"=>"Request Bad"),400);
}
}
else {
return Response::json(array("message"=>"Request not authorized"),401);
}
}
Making a get request http://api.xyz.com/v1/tasks/1?user_id=1&sig=41295da38eadfa56189b041a022c6ae0fdcbcd5e65c83f0e9aa0e6fbae666cd8 always returns a successful message even when i alter the value of the user_id parameter which should void the signature an make the request invalid.
It seems my verfiy_request method is not executing.
Please help me out
I have also been researching this recently and would also recommend going with filters. It could work something like this:
class Api_Tasks_Controller extends Base_Controller {
public $restful = true;
function __construct() {
// Check if user is authorized
$this->filter('before', 'api_checkauth');
}
// rest of the class ....
}
And in your routes.php file:
Route::filter('api_checkauth', function()
{
//user id
$user_id = (int) Input::get('user_id');
//signature
$sig = Input::get('sig');
try {
//Lookup user
$user = Sentry::user($user_id);
if($user) {
//user email
$email = $user->email;
//user api key
$api_key = $user->metadata['api_key'];
//recreate signature
$_sig = hash_hmac("sha256",$email.$user_id,$api_key);
if($_sig === $sig) {
return Response::json(array("message"=>"Request Ok"),200);
}
else {
return Response::json(array("message"=>"Request Bad"),400);
}
}
else {
return Response::json(array("message"=>"Request not authorized"),401);
}
}
catch (Sentry\SentryException $e) {
$errors = $e->getMessage(); // catch errors such as user not existing or bad fields
return Response::json(array("message"=>$errors),404);
}
});
Also, thanks for introducing me to Sentry :-)
It's a quick guess, I didn't try but maybe you might want to try to add a return statement before calling verify_request.
And you should look into filters which will allow you to separate more your api logic and
api authentication ;-)

Categories