Hi, I'm trying to figure out how to build a login authentication system in actix. I came across something promising which sends a notification asking for login credentials before allowing a user to enter a site and was looking to change it to one that operates through the submission of a form instead. How should I adjust the code to make it so that it operates off form data from a client?
[dependencies]
actix-web = "2.0.0"
actix-rt = "1.1.1"
actix-web-httpauth = "0.4.1"
use actix_web_httpauth::extractors::AuthenticationError;
use actix_web_httpauth::extractors::basic::{BasicAuth, Config};
use actix_web_httpauth::middleware::HttpAuthentication;
use actix_web::{web, App, HttpServer, Error, Responder, dev::ServiceRequest};
async fn index(info: web::Path<(u32, String)>) -> impl Responder
{
format!("Hello {}! id:{}", info.1, info.0)
}
fn validate_credentials(user_id: &str, user_password: &str) -> Result<bool, std::io::Error>
{
if user_id.eq("karl") && user_password.eq("password")
{
return Ok(true);
}
return Err(std::io::Error::new(std::io::ErrorKind::Other, "Authentication failed!"));
}
async fn basic_auth_validator(req: ServiceRequest, credentials: BasicAuth) -> Result<ServiceRequest, Error>
{
let config = req
.app_data::<Config>()
.map(|data| data.get_ref().clone())
.unwrap_or_else(Default::default);
match validate_credentials(credentials.user_id(), credentials.password().unwrap().trim())
{
Ok(res) =>
{
if res == true
{
Ok(req)
}
else
{
Err(AuthenticationError::from(config).into())
}
}
Err(_) => Err(AuthenticationError::from(config).into()),
}
}
#[actix_rt::main]
async fn main() -> std::io::Result<()>
{
HttpServer::new(move ||
{
let auth = HttpAuthentication::basic(basic_auth_validator);
App::new()
.wrap(auth)
.route("/{id}/{name}/index.html", web::get().to(index))
})
.bind("127.0.0.1:8080")?
.run()
.await
}