I have been creating user login form using the various groupcodes, the user login has to work based on the unique groupcodes.Let me explain these in detail there are two users called (X and Y) exists in the site with the following details
X loginname-testuser#gmail.com pwd- 123456 ,groupcode-TESTCODE
Y loginname-testuser#gmail.com pwd-test124, groupcode-TESTCODE2
My Authcontroller
$adapter = new Zend_Auth_Adapter_DbTable(Zend_Db_Table::getDefaultAdapter(),
'users',
'login',
'password',
'MD5(?)','groupcode','TESTCODE');
$adapter->setIdentity($form->getValue('username'))
->setCredential($form->getValue('password'));
$result = Zend_Auth::getInstance()->authenticate($adapter);
The result alwyas through the Authentication went Wrong error messsage. The default authcontroller takes the idenfity from the both the user rows, it doesn't takes from the user unique row value.
I'm not sure I completely understand the problem, but hopefully one of these solutions can help you.
First, you are passing 7 arguments to the Zend_Auth_Adapter_DbTable constructor, but its constructor only accepts 5 arguments, so groupcode and testcode have no effect in your code.
Since you are probably going to get more than 1 result, setting ambiguity identity flag may work for you. Set it by calling $adapter->setAmbiguityIdentity(true); so that if more than 1 result is returned, it will look at each one for a password match.
If you need to pass groupcode and testcode, then you probably need to create your own auth adapter. You could extend from Zend_Auth_Adapter_DbTable to take advantage of what it has already done, but override authenticate() so that it takes your groups into consideration.
Or, you could use Zend_Auth to check for an identity, but not use its authenticate method at all, and just write your own class to validate the user login, and then use Zend_Auth to set the identity.
Related
How I can manage to login with email address,not with the standart (username + password).I enter the website with my Users in my DataBase , but is there a way to change that to be with email address instead of that user name , because when I use Gii , I got a lot of errors , even I try to fix those errors
First, try to locate your SiteController or any other Controller you use for the index route. It should have an action function that corresponds to the login route; it is usually with signature public function actionLogin().
You should see the initialized model (usually, the LoginForm model). The model should have a function for login logic which is checked to determine user authenticity. You should find that this function invokes another login function which requires the User object as first argument/parameter. The function is usually the $this->getUser() function.
Looking into this will point to you a call to the actual data model that fetches user by whatever criteria/property you specify; this can be email or anything else that might not even need be unique but generally, you want to use a unique data property like username and email. This function relies on the User data model. It, by Gii default, calls the function User::findByUsername(search_property)
Yii2 provides a default User model that implements the Identity interface; that's where you want to make the adjustment you need. It should have the required static function findByUsername() or something similar. You would find that Yii2 default searches within static data to find user, you should link that to you (User) data model which I assume you generated using Gii.
My Gii sequence usually looks like such:
List item
Generate the yii2-basic/yii2-advanced using composer
Create Database (I have a user table in there) and set proper db credentials in config/db.php
Rename the default model/User.php to model/OldUser.php
Create Data Models using Gii
Make the newly generated User Model implement IdentityInterface to allow Yii2 freely-given session management by adding implements yii\web\IdentityInterface to the class declaration.
Implement all the required methods of the IdentityInterface. You can check in `model/OldUser.php' for guidance.
Create static functions to findUserByEmail($email) or findUserByUsername($username)
Mine usually look like this
I hope this helps.
I made it just change everywhere where must be email,instead of username,because of Yii default username loggin , thank u for the advices
I've been working with Sails since couple of weeks ago, I came from Rails and I don't have any experience working with Node.js.
Now I'm trying to make a robust token authentication using jsonwebtoken.
https://github.com/auth0/node-jsonwebtoken
I followed this guide http://thesabbir.com/how-to-use-json-web-token-authentication-with-sails-js/ and everything worked fine.
I'm able to make a sign up, sign in and then use the token correctly for different actions.
Now, there are some actions where I'd like to use the login user,
something like devise current_user helper.
For example, when creating a comment, this comment should belongs to the current user.
Using Sabbir Ahmed guide, in the line 33 from the isAuthorized.js policy the token gets decrypted so I can get the current user id from there.
So, my question is, what should be the best way to get the current user and be able to use it later in some controller?
For example I tried something like:
# isAuthorized.js line 34, after getting decrypted token
User.findOne({id: token.id}).exec(function findOneCB(err, found){
currentUser = found;
});
But, on this way, because this is an async action I can't use this currentUser in a controller.
I want to store the current user in order to be able to use it later in some controller without repeated the same code in each controller, something like a helper or maybe a service.
The trick is where you place the next(). Since you are making an async call, the control should only be transferred to next policy/ controller once the database action is competed.
You should modify the policy to:
User.findOne({id: token.id}).exec(function findOneCB(err, found){
if(err) next(err);
req.currentUser = found;
next();
});
And you should be able to access the user details in controllers that use isAuthorized policy via req.currentUser
If by
For example, when creating a comment, this comment should belongs to the current user.
what you mean is certain attributes like username, and country etc, rather than querying the database after verification, what you can choose to do is to send these additional attributes to jwToken.issue in api/controllers/UsersController.js
eg.
jwToken.issue({
id: user.id,
username: user.name,
country: user.country
})
How that helps is, you can keep api/policies/isAuthorized.js as is, and in all the controllers that you use in the future, you can access the payload values from as
token.username or token.country
Instead of having to query the database again, thereby saving you valuable response time.
Beware however, of the data you choose to send in the token (you could also send {user:user} if you want to) however, as the secret key or hashing is not required to decrypt the payload as you can figure # jwt.io , you might want to exercise restraint.
I don´t know how to securely pass a parameter via form with Cake.
The method I use now is as follows:
$this->Form->create('Post', array('label' => '', 'action' => '', 'url' => 'inseratAngenommen/'.$postId));
In the controller there stands:
function inseratAngenommen($id = null, $bs = null){
//stuff
}
The poblem is that the user can modify the output number of $postId in the browser:
action="/cakephp/posts/inseratAngenommen/149"
For that case I want to pass the parameter invisible in the HTML. Is that possible?
I thought of a method like the Form->PostLink provides. I couldn´t find anything.
Thanks in advance.
It is not possible to send an parameter securely over a website as the data is sent by the user.
Use the validation methods of cakephp to make sure the data is correct.
1] method one: add obscurity: hide the $id into a posted field by:
$this->Form->hidden('id');
$this->Form-field('id'); // even this one will do as cake hides ids by default
2] method two: keep the id on the server for instance in a session
$this->Session->write('current-edited-post-id', $id); // upon form display
$id = $this->Session->read('current-edited-post-id'); // upon form submission
but be warned thou, that method 2 doesn't behave well, if the user opens multiple tabs and operates one session from both of them :(
Not sure if this is a security feature, an oversight, or me missing the ocean for the waves, but wondering why there is no value attribute for the password field constructor
This is not an issue for user signup and other form creation events, but becomes a headache when, for example, a user renewal form does not have the password field filled in (and thus fails validation, which is ironic given that they just logged in in order to be able to renew in the first place ;-))
My workaround has been to set the value attrib manually by supplying it as an extra argument:
#inputPassword(
_form("password"), '_label-> "Password*", 'class-> "required",
'value-> _form("password").value map{Some(_)} getOrElse Some("")
)
would prefer the value attribute included by default, however, as with other input elements. Yes, I can override it, but wondering what the dealy-O is regardless
To me, you shouldn't be able to retrieve the user password in any way, since the password should be encrypted before storing it somewhere.
I'm writing tests for my current project, made with Zend Framework.
Everything's fine, but I have a problem testing the logged users actions/controllers: I need to be logged in to be able to perform the action/controller.
How can I be logged in PHPUnit?
As you are saying you want to test actions/controllers, I suppose you are not writting unit-tests, but functional/integration tests -- ie, working with Zend_Test and testing via the MVC.
Here is a test-function I used in a project, where I'm testing if logging in is OK :
public function testLoggingInShouldBeOk()
{
$this->dispatch('/login/login');
$csrf = $this->_getLoginFormCSRF();
$this->resetResponse();
$this->request->setPost(array(
'login' => 'LOGIN',
'password' => 'PASSWORD',
'csrfLogin' => $csrf,
'ok' => 'Login',
));
$this->request->setMethod('POST');
$this->dispatch('/login/login');
$this->assertRedirectTo('/');
$this->assertTrue(Zend_Auth::getInstance()->hasIdentity());
}
Simply : I'm loading the login form, extracting the CSRF token, populating the form, and posting it.
Then, I can test if I'm connected.
With that, you can probably extract the logging-in part, to call it before each one of your tests that require a valid user to be logged-in.
There is another way. On my User entity I have a login() method that puts the user's id into the session and a static variable. What I just do in the test setUp() is call $user->login() and it works. In testing environment sessions are not used (setting Zend_Session::$isUnitTested = true has this effect) and tests rely on the static variable. Just remember to clear the static variable (logout() the user) on tearDown().
I think this article could help you:
http://perevodik.net/en/posts/7/
It describes how to create a fake identity you can use to set the environment to a state equivalent to a user being logged in.
In much the same way Pascal is using this function:
$this->_getLoginFormCSRF();
I have created a generic function that returns the value by loading the form using the form element manager:
public function _getCSRFHashValueFromForm($formAlias, $csrfName) {
$form = $this->servicemanager->get('FormElementManager')->get($formAlias);
return $form->get($csrfName)->getValue(); }
This of course assumes that the CSRF is bound to the form and not within any fieldset etc.