我正在尝试使用android创建安全登录名,但是由于注册功能不起作用,因此我无法测试其功能。我已确保我已正确连接到数据库,并且目前没有收到任何错误。
此文件包含用于检查用户是否不存在的功能,用于生成密码盐和哈希的功能。我使用了随机盐生成器,以便为每个用户生成唯一的盐和哈希。
<?php
$random_salt_length = 32;
function userExists($username){
$query = "SELECT username FROM member WHERE username = ?";
global $con;
if($stmt = $con->prepare($query)){
$stmt->bind_param("s",$username);
$stmt->execute();
$stmt->store_result();
$stmt->fetch();
if($stmt->num_rows == 1){
$stmt->close();
return true;
}
$stmt->close();
}
return false;
}
function getSalt(){
global $random_salt_length;
return bin2hex(openssl_random_pseudo_bytes($random_salt_length));
}
function concatPasswordWithSalt($password,$salt){
global $random_salt_length;
if($random_salt_length % 2 == 0){
$mid = $random_salt_length / 2;
}
else{
$mid = ($random_salt_length - 1) / 2;
}
return
substr($salt,0,$mid - 1).$password.substr($salt,$mid,$random_salt_length - 1);
}
?>
<?php
$response = array();
include 'db/db_connect.php';
include 'functions.php';
//Get the input request parameters
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE); //convert JSON into array
//Check for Mandatory parameters
if(isset($input['username']) && isset($input['password']) && isset($input['full_name'])){
$username = $input['username'];
$password = $input['password'];
$fullName = $input['full_name'];
//Check if user already exist
if(!userExists($username)){
//Get a unique Salt
$salt = getSalt();
//Generate a unique password Hash
$passwordHash = password_hash(concatPasswordWithSalt($password,$salt),PASSWORD_DEFAULT);
//Query to register new user
$insertQuery = "INSERT INTO member(username, full_name, password_hash, salt) VALUES (?,?,?,?)";
if($stmt = $con->prepare($insertQuery)){
$stmt->bind_param("ssss",$username,$fullName,$passwordHash,$salt);
$stmt->execute();
$response["status"] = 0;
$response["message"] = "User created";
$stmt->close();
}
}
else{
$response["status"] = 1;
$response["message"] = "User exists";
}
}
else{
$response["status"] = 2;
$response["message"] = "Missing mandatory parameters";
}
echo json_encode($response);
?>
public class RegisterActivity extends AppCompatActivity {
private static final String KEY_STATUS = "status";
private static final String KEY_MESSAGE = "message";
private static final String KEY_FULL_NAME = "full_name";
private static final String KEY_USERNAME = "username";
private static final String KEY_PASSWORD = "password";
private static final String KEY_EMPTY = "";
private EditText etUsername;
private EditText etPassword;
private EditText etConfirmPassword;
private EditText etFullName;
private String username;
private String password;
private String confirmPassword;
private String fullName;
private ProgressDialog pDialog;
private String register_url = "http://10.0.0.1/members/register.php";
private SessionHandler session;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
session = new SessionHandler(getApplicationContext());
setContentView(R.layout.activity_register);
etUsername = findViewById(R.id.etUsername);
etPassword = findViewById(R.id.etPassword);
etConfirmPassword = findViewById(R.id.etConfirmPassword);
etFullName = findViewById(R.id.etFullName);
Button login = findViewById(R.id.btnRegisterLogin);
Button register = findViewById(R.id.btnRegister);
//Launch Login screen when Login Button is clicked
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(RegisterActivity.this, LoginActivity.class);
startActivity(i);
finish();
}
});
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Retrieve the data entered in the edit texts
username = etUsername.getText().toString().toLowerCase().trim();
password = etPassword.getText().toString().trim();
confirmPassword = etConfirmPassword.getText().toString().trim();
fullName = etFullName.getText().toString().trim();
if (validateInputs()) {
registerUser();
}
}
});
}
// Display Progress bar while registering
private void displayLoader() {
pDialog = new ProgressDialog(RegisterActivity.this);
pDialog.setMessage("Signing Up.. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
// Launch Dashboard Activity on Successful Sign Up
private void loadDashboard() {
Intent i = new Intent(getApplicationContext(), DashboardActivity.class);
startActivity(i);
finish();
}
private void registerUser() {
displayLoader();
JSONObject request = new JSONObject();
try {
//Populate the request parameters
request.put(KEY_USERNAME, username);
request.put(KEY_PASSWORD, password);
request.put(KEY_FULL_NAME, fullName);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsArrayRequest = new JsonObjectRequest
(Request.Method.POST, register_url, request, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
pDialog.dismiss();
try {
//Check if user got registered successfully
if (response.getInt(KEY_STATUS) == 0) {
//Set the user session
session.loginUser(username,fullName);
loadDashboard();
}else if(response.getInt(KEY_STATUS) == 1){
//Display error message if username is already existing
etUsername.setError("Username already taken!");
etUsername.requestFocus();
}else{
Toast.makeText(getApplicationContext(),
response.getString(KEY_MESSAGE), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
pDialog.dismiss();
//Display error message whenever an error occurs
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
// Access the RequestQueue through your singleton class.
VolleySingleton.getInstance(this).addToRequestQueue(jsArrayRequest);
}
public class SessionHandler {
private static final String PREF_NAME = "UserSession";
private static final String KEY_USERNAME = "username";
private static final String KEY_EXPIRES = "expires";
private static final String KEY_FULL_NAME = "full_name";
private static final String KEY_EMPTY = "";
private Context mContext;
private SharedPreferences.Editor mEditor;
private SharedPreferences mPreferences;
public SessionHandler(Context mContext) {
this.mContext = mContext;
mPreferences = mContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
this.mEditor = mPreferences.edit();
}
public void loginUser(String username, String fullName) {
mEditor.putString(KEY_USERNAME, username);
mEditor.putString(KEY_FULL_NAME, fullName);
Date date = new Date();
//Set user session for next 7 days
long millis = date.getTime() + (7 * 24 * 60 * 60 * 1000);
mEditor.putLong(KEY_EXPIRES, millis);
mEditor.commit();
}
public boolean isLoggedIn() {
Date currentDate = new Date();
long millis = mPreferences.getLong(KEY_EXPIRES, 0);
/* If shared preferences does not have a value
then user is not logged in
*/
if (millis == 0) {
return false;
}
Date expiryDate = new Date(millis);
/* Check if session is expired by comparing
current date and Session expiry date
*/
return currentDate.before(expiryDate);
}
public User getUserDetails() {
//Check if user is logged in first
if (!isLoggedIn()) {
return null;
}
User user = new User();
user.setUsername(mPreferences.getString(KEY_USERNAME, KEY_EMPTY));
user.setFullName(mPreferences.getString(KEY_FULL_NAME, KEY_EMPTY));
user.setSessionExpiryDate(new Date(mPreferences.getLong(KEY_EXPIRES, 0)));
return user;
}
/**
* Logs out user by clearing the session
*/
public void logoutUser(){
mEditor.clear();
mEditor.commit();
}
}
您能不能向我正确的方向推我,因为我无法弄清楚我要去哪里错了
答案 0 :(得分:0)
如果未显示任何错误消息,但没有任何内容写入数据库,则可能是查询无法执行。
register.php
中的这段代码目前没有任何错误检查:
//Query to register new user
$insertQuery = "INSERT INTO member(username, full_name, password_hash, salt) VALUES (?,?,?,?)";
if($stmt = $con->prepare($insertQuery)){
$stmt->bind_param("ssss",$username,$fullName,$passwordHash,$salt);
$stmt->execute();
$response["status"] = 0;
$response["message"] = "User created";
$stmt->close();
}
这可能会在两个地方失败:
$con->prepare()
可能会失败,例如由于语法错误或由于表或列名不存在或您的用户没有权限对该表执行INSERT查询而导致的错误$stmt->execute()
可能会失败。如果您要在仅接受整数值的列中插入字符串。您应该对此添加一些额外的检查。在某些时候,您将需要向您的应用程序提供有用的错误消息,以使用户不会遇到无法解决的技术问题,但是暂时在调试时,我建议将错误消息转储到此处(看来状态> 1
表示错误,如果我错了,请纠正我):
//Query to register new user
$insertQuery = "INSERT INTO member(username, full_name, password_hash, salt) VALUES (?,?,?,?)";
if($stmt = $con->prepare($insertQuery)){
$stmt->bind_param("ssss",$username,$fullName,$passwordHash,$salt);
if ($stmt->execute()) {
$response["status"] = 0;
$response["message"] = "User created";
} else {
$response["status"] = 2;
$response["message"] = $stmt->error;
}
$stmt->close();
} else {
$response["status"] = 2;
$response["message"] = $con->error;
}