我用 actix 制作了一个 web 服务,我正在尝试使用 Actix-Web 1.0 - Complete Tutorial 来实现 Auth Web Microservice with Rust中的身份验证流程:
use std::sync::Arc;
use std::sync::Mutex;
use actix_cors::Cors;
use actix_identity::{CookieIdentityPolicy, Identity, IdentityService};
use actix::prelude::*;
use actix::{Actor, SyncContext};
use actix_web::{
dev::Payload, error, guard, http::header, middleware, web, App, Error as AWError, FromRequest,
HttpRequest, HttpResponse, HttpServer, Responder, ResponseError,
};
use derive_more::Display;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TokenResult {
pub company: String,
pub config: String,
}
#[derive(Debug, Display)]
pub enum ServiceError {
#[display(fmt = "Internal Server Error")]
InternalServerError(String),
#[display(fmt = "BadRequest: {}", _0)]
BadRequest(String),
#[display(fmt = "Unauthorized")]
Unauthorized,
}
impl ResponseError for ServiceError {
fn error_response(&self) -> HttpResponse {
match *self {
ServiceError::InternalServerError(ref message) => {
HttpResponse::InternalServerError().json(message)
}
ServiceError::BadRequest(ref message) => HttpResponse::BadRequest().json(message),
ServiceError::Unauthorized => HttpResponse::Unauthorized().json("Unauthorized"), //This is executed
}
}
}
impl FromRequest for TokenResult {
type Error = AWError;
type Future = Result<TokenResult, Self::Error>;
type Config = ();
fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future {
if let Some(identity) = Identity::from_request(req, pl)?.identity() {
let user: TokenResult = serde_json::from_str(&identity)?;
return Ok(user);
}
//This is executed
Err(ServiceError::Unauthorized.into())
}
}
fn client_config(token: TokenResult) -> HttpResponse {
HttpResponse::Ok().json(token.config)
}
fn main() -> Result<(), AWError> {
let sys = actix_rt::System::new("Api");
let mut server = HttpServer::new(move || {
App::new()
.wrap(IdentityService::new(
CookieIdentityPolicy::new(&[0; 32])
.name("auth-cookie")
.secure(false),
))
.service(web::resource("/config").to(client_config))
});
server = server.bind("127.0.0.1:8080").unwrap();
server.start();
println!("Started http client: 127.0.0.1:8080");
sys.run()?;
Ok(())
}
当我使用 httpie 和其他人进行测试时,我得到的是文本而不是 JSON:
http -v POST http://localhost:8080/config
POST /config HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 0
Host: localhost:8080
User-Agent: HTTPie/1.0.2
HTTP/1.1 401 Unauthorized
content-length: 12
content-type: text/plain
date: Tue, 10 Sep 2019 20:41:46 GMT
Unauthorized
TokenResult
除了返回 JSON之外的所有其他方法和错误。
我的依赖:
[dependencies]
actix = "0.8.3"
actix-files = "0.1.4"
actix-rt = "0.2.5"
actix-identity = "0.1.0"
actix-cors = "0.1.0"
actix-web = {version = "1.0.7", features=["flate2-rust"], default-features = false}
derive_more = "0.15.0"
futures = "0.1.29"
json = "0.12.0"
serde = { version = "1.0.100", features = ["derive"] }
serde_json = "1.0.40"
snafu = "0.5.0"