Sign-up handler

To handle sign-up requests, we need a POST method handler for the /signup path. We can declare it in the following way:

(POST) (/signup) => {
let data = post_input!(request, {
email: String,
password: String,
})?;
let user_email = data.email.trim().to_lowercase();
let user_password = pbkdf2_simple(&data.password, 12345)?;
{
use self::schema::users::dsl::*;
let conn = pool.get()?;
let user_exists: bool = select(exists(users.filter(email.eq(user_email.clone()))))
.get_result(&conn)?;
if !user_exists {
let uuid = format!("{}", uuid::Uuid::new_v4());
let new_user = models::NewUser {
id: &uuid,
email: &user_email,
password: &user_password,
};
diesel::insert_into(schema::users::table).values(&new_user).execute(&conn)?;
Response::json(&())
} else {
Response::text(format!("user {} exists", data.email))
.with_status_code(400)
}
}
}

This handler is more complex and also demonstrates how to parse the parameters of a request. We need to parse an HTML form with two parameters—email and password. To do this, we used the post_input! macro, which expects a request instance and a form declaration with types. The form structure declaration looks like a simple struct declaration without a name, but with fields. We added two necessary fields and the post_input! macro parsed a request to fill an object with the corresponding fields.

Since parsed parameters only fit types, we also had to add extra processing to it. The email field is a String type, and we used the trim method to remove unnecessary spacing and the to_lowercase method to convert it to lowercase. We used the password field without any changes and passed it as a parameter to the pbkdf2_simple method of the rust-crypto crate.

PBKDF2 is an algorithm that adds computational cost to an encrypted value to prevent brute-force attacks. If your microservice is attacked and your password is stolen, it won't be easy for attackers to find a password value to access the service with someone else's account. If you use hashes, then the attacker will be able to find the matching password quickly.

After we prepared parameters, we used them with object-relational mapping methods. First, to check whether the user with the provided email exists, we use a DSL generated by the diesel crate and, if the user doesn't exist, we generate a unique ID for the user using the uuid crate. The handler fills the NewUser instance with corresponding values and inserts it into a database. Upon success, it returns an empty JSON response. If the user already exists, the handler returns a response with a 400 status code (Bad Response) with a message to the effect that the user with the provided email already exists. Let's look at how to sign in with a stored user value.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.109.234