Rust에서 양식 유효성 검사(Actix-Web)
13323 단어 rustactixvalidationwebdev
사용 도구 : -
Actix-Web : Rust를 위한 강력하고 실용적이며 매우 빠른 웹 프레임워크
Validator: marshmallow 및
Django validators
lazy_static : Rust에서 느리게 평가된 통계를 선언하기 위한 매크로입니다.
regex : Rust용 정규식 구현.
종속성
'./Cargo.toml'
[dependencies]
actix-web = "4"
validator = { version = "0.12", features = ["derive"] }
serde = { version = "1.0.104", features = ["derive"] }
lazy_static = "1.4.0"
regex = "1.5.6"
러스티를 얻자
Rust 프로젝트 초기화
다음
cargo new <file-name>
으로 새 프로젝트를 시작합니다.기본 actix 서버 구현
actix official docs 에서 샘플 코드를 복제해 보겠습니다.
use actix_web::{get, web, App, HttpServer, Responder};
#[get("/hello/{name}")]
async fn greet(name: web::Path<String>) -> impl Responder {
format!("Hello {name}!")
}
#[actix_web::main] // or #[tokio::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/hello", web::get().to(|| async { "Hello World!" }))
.service(greet)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
데이터를 담을 구조체 만들기
이 프로젝트에서는 학생 모델/구조체를 만들고 있습니다.
pub struct Student {
pub name: String,
pub email: String,
pub age: u32,
pub username: String,
pub password: String,
}
Serde Serialize 및 Deserialize 특성 구현
json 데이터를 구조체로 또는 그 반대로 변환합니다.
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct Student {
pub name: String,
....
}
더 읽을 수 있습니다 here
경로 및 핸들러 생성
json 형태의 데이터를 받아들이고, 검증하고 검증의 성공 여부에 따라 응답을 반환하는 포스트 라우트가 될 것입니다.
노선
'./src/main.rs
async fn main() -> std::io::Result<()> {
....
HttpServer::new(|| {
App::new()
.route("/", web::post().to(create_student))
})
....
}
'./src/main.rs
매니저
pub async fn create_student(json: web::Json<Student>) -> impl Responder {
let is_valid = json.validate();
match is_valid {
Ok(_) => HttpResponse::Ok().json("success"),
Err(err) => HttpResponse::BadRequest().json(err),
}
}
여기서
let is_valid = json.validate();
라인은 유효성 검사기를 구현합니다. 이제 정의 유효성 검사 규칙을 정의할 수 있습니다.유효성 검사 규칙 만들기
validator.rs에서 Validator 특성을 파생시켜 보겠습니다.
serde Serialize 및 Deserialize 특성과 함께 유효성 검사기 특성을 추가합니다.
use validator::Validate;
#[derive(Serialize, Deserialize, Validate)]
pub struct Student {
....
}
그러나 Student Struct에 대한 요구 사항은 무엇입니까?
이름 : 3자 이상이어야 합니다.
이메일 : 유효한 Gmail 주소여야 합니다.
나이 : 18세에서 22세 사이여야 합니다.
비밀번호 : 영문 소문자 최소 1개, 영문 대문자 최소 1개, 숫자 최소 1개, 특수문자 최소 1개로 총 8자리여야 합니다. 공백이 없습니다.
사용자 이름 : 영숫자와 6자 길이여야 합니다.
구현 조건
이름 :
#[validate(length(min = 3,message = "Name must be greater than 3 chars"))]
pub name: String
길이 : 데이터의 길이가 정의된 길이보다 크거나 작아야 함을 보장합니다.
message : 오류를 표시하는 클라이언트 측 메시지입니다.
이메일 :
#[validate(
email,
contains(pattern = "gmail", message = "Email must be valid gmail address")
)]
pub email: String,
}
이메일 : 이메일에 @ 기호, 도메인 이름 및 .com 및 사용자 ID와 같은 확장자와 같은 요구 사항이 포함되어 있는지 확인합니다.
포함 및 패턴 : 특정 문자열이 특정 하위 단어(패턴)를 포함해야 하며 여기서는 gmail임을 확인합니다.
나이 :
#[validate(range(min = 18, max = 22, message = "Age must be between 18 to 22"))]
pub age: u32,
범위 : 크기가 특정 범위에 속하도록 강제합니다.
사용자 이름 :
lazy_static! {
static ref RE_USER_NAME: Regex = Regex::new(r"^[a-zA-Z0-9]{6,}$").unwrap();
}
pub struct Student {
....
#[validate(
regex(
path = "RE_USER_NAME",
message = "Username must number and alphabets only and must be 6 characters long"
)
)]
pub username: String,
....
}
lazy_static: Rust에서 Lazy는 정적을 평가했습니다. 벡터 또는 해시 맵 등과 같이 힙 할당이 필요한 모든 것을 포함하여 런타임에 실행됩니다.
regex : 일치하는 경로/패턴이 필요합니다. 사용된 regex 패턴에 대한 자세한 내용은 다음을 참조하십시오.
비밀번호 :
lazy_static! {
static ref RE_SPECIAL_CHAR: Regex = Regex::new("^.*?[@$!%*?&].*$").unwrap();
}
fn validate_password(password: &str) -> Result<(), ValidationError> {
let mut has_whitespace = false;
let mut has_upper = false;
let mut has_lower = false;
let mut has_digit = false;
for c in password.chars() {
has_whitespace |= c.is_whitespace();
has_lower |= c.is_lowercase();
has_upper |= c.is_uppercase();
has_digit |= c.is_digit(10);
}
if !has_whitespace && has_upper && has_lower && has_digit && password.len() >= 8 {
Ok(())
} else {
return Err(ValidationError::new("Password Validation Failed"));
}
}
pub struct Student {
....
#[validate(
custom(
function = "validate_password",
message = "Must Contain At Least One Upper Case, Lower Case and Number. Dont use spaces."
),
regex(
path = "RE_SPECIAL_CHAR",
message = "Must Contain At Least One Special Character"
)
)]
pub password: String,
....
}
custom : 유효성 검사를 구현하는 함수가 필요하며 메시지 인수로 사용자 지정 메시지를 추가할 수도 있습니다.
완전한 코드
extern crate lazy_static;
extern crate regex;
extern crate serde;
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use lazy_static::lazy_static;
use regex::Regex;
use serde::{Deserialize, Serialize};
use validator::{Validate, ValidationError};
lazy_static! {
static ref RE_USER_NAME: Regex = Regex::new(r"^[a-zA-Z0-9]{6,}$").unwrap();
static ref RE_SPECIAL_CHAR: Regex = Regex::new("^.*?[@$!%*?&].*$").unwrap();
}
#[derive(Serialize, Deserialize, Validate)]
pub struct Student {
#[validate(length(min = 3, message = "Name must be greater than 3 chars"))]
pub name: String,
#[validate(
email,
contains(pattern = "gmail", message = "Email must be valid gmail address")
)]
pub email: String,
#[validate(range(min = 18, max = 22, message = "Age must be between 18 to 22"))]
pub age: u32,
#[validate(
regex(
path = "RE_USER_NAME",
message = "Username must number and alphabets only and must be 6 characters long"
)
)]
pub username: String,
#[validate(
custom(
function = "validate_password",
message = "Must Contain At Least One Upper Case, Lower Case and Number. Dont use spaces."
),
regex(
path = "RE_SPECIAL_CHAR",
message = "Must Contain At Least One Special Character"
)
)]
pub password: String,
}
fn validate_password(password: &str) -> Result<(), ValidationError> {
let mut has_whitespace = false;
let mut has_upper = false;
let mut has_lower = false;
let mut has_digit = false;
for c in password.chars() {
has_whitespace |= c.is_whitespace();
has_lower |= c.is_lowercase();
has_upper |= c.is_uppercase();
has_digit |= c.is_digit(10);
}
if !has_whitespace && has_upper && has_lower && has_digit && password.len() >= 8 {
Ok(())
} else {
return Err(ValidationError::new("Password Validation Failed"));
}
}
pub async fn create_student(json: web::Json<Student>) -> impl Responder {
let is_valid = json.validate();
match is_valid {
Ok(_) => HttpResponse::Ok().json("success"),
Err(err) => HttpResponse::BadRequest().json(err),
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Starting the server at http://127.0.0.1:8080/");
HttpServer::new(|| App::new().route("/", web::post().to(create_student)))
.bind(("127.0.0.1", 8080))?
.run()
.await
}
확인 중
actix 서버를
cargo run
까지 회전시켜 봅시다.비밀번호 확인
유효 탑재량
{
"name":"prave",
"email":"[email protected]",
"age":19,
"username":"praveee",
"password":"123@4aA"
}
산출
이름 확인
유효 탑재량
{
"name":"pr",
"email":"[email protected]",
"age":19,
"username":"praveee",
"password":"123d@4aA"
}
산출
이메일 확인
유효 탑재량
{
"name":"praveen",
"email":"[email protected]",
"age":19,
"username":"praveee",
"password":"123d@4aA"
}
산출
연령 확인
유효 탑재량
{
"age": [
{
"code": "range",
"message": "Age must be between 18 to 22",
"params": {
"min": 18.0,
"value": 4,
"max": 22.0
}
}
]
}
산출
사용자 이름 확인
유효 탑재량
{
"name":"praveen",
"email":"[email protected]",
"age":19,
"username":"prsdfdgfd@e",
"password":"123d@4aA"
}
산출
GitHub에서 자유롭게 질문하고 변경 사항 및 제안을 요청하십시오.
소스 코드
Github Repo Link
해피해킹
러스타시안!
Reference
이 문제에 관하여(Rust에서 양식 유효성 검사(Actix-Web)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/chaudharypraveen98/form-validation-in-rust-404l텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)