Reputation: 597
I have 3 input fields: username, password and type.
If either of the 3 were incorrect, I only get 1 error message which states "usern & pass is not correct".
How can I breakdown the error message so that it shows me that whether the values for password, username or type were entered incorrectly.
These are the 2 files I used: Login Model and LoginController. BTW, there is no error with the code below.
It works perfectly. I just want to expand it to breakdown the error message.
LoginController file:
public class LoginController implements Initializable {
/**
* Initializes the controller class.
*/
public LoginModel loginModel = new LoginModel();
@FXML private Label isConnected;
@FXML private JFXTextField txtUsername;
@FXML private JFXPasswordField txtPassword;
@FXML private ComboBox<String> comboType;
ObservableList<String> list = FXCollections.observableArrayList("admin", "manager", "clerk");
@Override
public void initialize(URL url, ResourceBundle rb) {
comboType.setItems(list);
if(loginModel.isDbConnected()) {
isConnected.setText("Connected");
}
else {
isConnected.setText("Not Connected");
}
}
public void Login (ActionEvent event) {
try {
if(loginModel.isLogin(comboType.getValue(), txtUsername.getText(), txtPassword.getText())) {
isConnected.setText("usern & pass is correct");
//closes login fxml file
((Node)event.getSource()).getScene().getWindow().hide();
//loads main interface fxml file
Stage primaryStage = new Stage();
FXMLLoader loader = new FXMLLoader();
Pane root = loader.load(getClass().getResource("/gui/uicomponents/Main.fxml").openStream());
MainController mainController = (MainController)loader.getController();
mainController.getUser("Hi " + txtUsername.getText());
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("/resources/css/Consolidated.css").toExternalForm());
primaryStage.setMaximized(true);
primaryStage.setTitle("Main Interface");
primaryStage.setScene(scene);
primaryStage.show();
}
else {
isConnected.setText("usern & pass is not correct");
}
} catch (SQLException ex) {
isConnected.setText("usern & pass is not correct");
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
LoginModel File:
public class LoginModel {
Connection connection;
public LoginModel() {
connection = SqliteConnection.Connector();
if(connection == null) {
System.out.println("Connection to DB Failed");
System.exit(1);
}
}
public boolean isDbConnected() {
try {
return !connection.isClosed();
} catch (SQLException ex) {
Logger.getLogger(LoginModel.class.getName()).log(Level.SEVERE, null, ex);
return false;
}
}
public boolean isLogin(String type, String user, String pass) throws SQLException {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
String query = "select * from users where type = ? and username = ? and password = ?";
try {
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, type);
preparedStatement.setString(2, user);
preparedStatement.setString(3, pass);
resultSet = preparedStatement.executeQuery();
//if returns result from db
if(resultSet.next()) {
return true;
}
else {
return false;
}
}
catch(Exception e) {
System.out.println(e);
return false;
}
finally {
preparedStatement.close();
resultSet.close();
}
}
}
Upvotes: 0
Views: 55
Reputation: 22442
It is NOT a good practice from the security perspective that to reveal which portion of the details are incorrect, i.e., it makes your application more vulnerable to the hackers because you are giving more hints saying that whether the userid
is incorrect or password
is incorrect or type
is incorrect.
But, if you really wanted to show the very specific error messages because of your own project requirements, you can achieve that by checking the Type
and UserName
exist or NOT and then defining & throwing the custom exceptions like TypeNotFoundException
or UserNameNotFoundException
exceptions as shown below:
Login() method:
public void Login (ActionEvent event) {
try {
if(loginModel.isLogin(comboType.getValue(),
txtUsername.getText(), txtPassword.getText())) {
//add your code
}
else {
isConnected.setText(" pass is not correct");
}
} catch (TypeNotFoundException ex) {
isConnected.setText("Type is not correct");
//add your logger
} catch (UserNameNotFoundException ex) {
isConnected.setText("Username is not correct");
//add your logger
} catch (SQLException ex) {
isConnected.setText("technical problem,please try after some time");
//add your logger
} catch (IOException ex) {
//add your logger
}
}
isLogin():
public boolean isLogin(String type, String user, String pass) throws SQLException {
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
String query = "select * from users where type = ?
and username = ? and password = ?";
try {
//other code
//if returns result from db
if(resultSet.next()) {
return true;
}
else {
//String typeQuery = "select * from users where type = ?";
//Execute the typeQuery and throw TypeNotFoundException
//String userNameQuery = "select * from users where username = ?";
//Execute the userNameQuery and throw UserNameNotFoundException
return false;
}
} //other code as is
}
Upvotes: 2
Reputation: 140525
Simply spoken, your method isLogin() would need to do more distinct analysis of the incoming data.
For example, you could first check if the user name is known at all.
But you see ; from a security point of view you probably don't want to give such details to the user. Assume an attacker is guessing user names. When you give him different messages for user unknown and password invalid ; then you help him attacking you. You could maybe put such information into a log file, but don't have to give all the details to the use!
And talking about security: it seems that you intend to store the password as plain text in your database. That is an absolute NO GO!
But given the fact that your clients talk to the database directly, security does not seem to be your first priority anyway.
Upvotes: 1