I'm using Play 2.1 and securesocial master snapshot.
I've implemented find & save of UserService (extends UserServicePlugin) as follows:
Find method as below:
def find(userId: UserId): Option[Identity] = {
val user = User.findByUserId(userId);
user match {
case Some(user) => {
val socialUser = new SocialUser(userId, null, null, user.name, Option(user.email), Option(user.photo), AuthenticationMethod("userPassword"), null, null, Some(PasswordInfo(PasswordHasher.BCryptHasher, BCrypt.hashpw(user.password, BCrypt.gensalt(10)))))
Option(socialUser)
}
case None => {
None
}
}
}
Save method as below:
def save(user: Identity): Identity = {
user.id.providerId match {
case "facebook" => {
}
case "google" => {
}
case "twitter" => {
}
case "userpass" => {
val eUser = User.findByEmail(user.id.id) match {
case Some(eUser) => {
//Existing User - update only
}
case None => {
val appUser: User = new User(NotAssigned, "student", user.id.providerId, user.fullName, user.id.id, user.passwordInfo.get.password, null, null, null, null, null, "active")
User.create(appUser)
}
}
}
}
user
}
When saving (signup) the password is being encrpted into the database, I'm not sure whether it should be encrypted or not and the above always says "The credentials you entered are not valid."
But if I use the word "password" (String) instead of user.password (from database) in find method like below it valids the credentials correctly, and logs me in:
val socialUser = new SocialUser(userId, null, null, user.name, Option(user.email), Option(user.photo), AuthenticationMethod("userPassword"), null, null, Some(PasswordInfo(PasswordHasher.BCryptHasher, BCrypt.hashpw("password", BCrypt.gensalt(10)))))
Here I think it is again trying to encrypt the password from the database (which is already encrypted) ... I guess, I should either save the password without encrypting or get the password entered by the user in login page to use in find method. Could anyone please help me, thanks.
I believe the following are the two entry points for all Social Networks & the UserPass provider!
Providers entry points
GET /authenticate/:provider securesocial.controllers.ProviderController.authenticate(provider)
POST /authenticate/:provider securesocial.controllers.ProviderController.authenticateByPost(provider)
I think these implementations comes with the securesocial plugin? or should be replicate the same? Is it the best solution!!
I'm using MySQL and the below is my table:
create table t_users (
id int unsigned not null auto_increment,
user_type enum('admin', 'user') not null default 'user',
login_type set('userpass', 'facebook', 'google', 'twitter') not null default 'userpass',
name varchar(64) not null,
email varchar(128) null,
password varchar(128),
mobile varchar(10) null,
facebook varchar(64) null,
google varchar(64) null,
twitter varchar(64) null,
photo varchar(128),
status enum('registered', 'active', 'suspended', 'deleted') not null default 'registered',
modified timestamp not null,
last_login timestamp not null,
primary key (id),
unique(email),
unique(facebook),
unique(google),
unique(twitter)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
The correct find method as below:
You need to use
BCrypt.checkpw(suppliedPassword, hashedPassword)
somewhere.So yes, you should be saving the hashed password to the database. Then when a user supplies a password on your login screen you should retrieve the hashed password for the user from your database, call checkpw, then if it returns true then log the user in.