Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const SECRET: &str = "randomString";
- #[derive(Deserialize, Serialize)]
- pub struct Claims {
- pub exp: usize,
- pub iat: usize,
- pub user: String,
- }
- #[derive(Clone, Debug)]
- pub struct User {
- pub username: String,
- pub password_hash: String,
- }
- impl AuthUser for User {
- type Id = String;
- fn id(&self) -> Self::Id {
- self.username.clone()
- }
- fn session_auth_hash(&self) -> &[u8] {
- self.password_hash.as_bytes()
- }
- }
- fn resolve_jwt(token: &str) -> Result<TokenData<Claims>, StatusCode> {
- decode::<Claims>(
- token,
- &DecodingKey::from_secret(SECRET.as_bytes()),
- &Validation::default(),
- )
- .map_err(|_| StatusCode::UNAUTHORIZED)
- }
- fn retrive_user(username: String) -> Option<User> {
- Some(User {
- username,
- password_hash: "".into(),
- })
- }
- pub fn verify_password(password: String, hash: String) -> Result<bool, BcryptError> {
- verify(password, &hash)
- }
- fn encode_token(user: String) -> Result<String, StatusCode> {
- let now = Utc::now();
- let exp = (now + OtherDuration::hours(24)).timestamp() as usize;
- let iat = now.timestamp() as usize;
- let claims = Claims { exp, iat, user };
- encode(
- &Header::default(),
- &claims,
- &EncodingKey::from_secret(SECRET.as_bytes()),
- )
- .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)
- }
- pub struct JwtToken(pub String);
- pub async fn sign_in(
- State(_state): State<Backend>,
- Json(request): Json<LoginData>,
- ) -> Result<Json<ResponseMessage>, StatusCode> {
- let user = retrive_user(request.user.clone()).ok_or(StatusCode::UNAUTHORIZED)?;
- if !verify_password(request.password, user.password_hash.clone())
- .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
- {
- return Err(StatusCode::UNAUTHORIZED);
- }
- let token = encode_token(user.username)?;
- Ok(Json(ResponseMessage { response: token }))
- }
- #[derive(Debug, Deserialize, Clone)]
- pub struct LoginData {
- pub user: String,
- pub password: String,
- }
- #[derive(Clone, Default)]
- pub struct Backend {
- pub users: HashMap<String, User>,
- }
- #[async_trait]
- impl AuthnBackend for Backend {
- type User = User;
- type Credentials = String;
- type Error = Infallible;
- async fn authenticate(
- &self,
- token: Self::Credentials,
- ) -> Result<Option<Self::User>, Self::Error> {
- let user = resolve_jwt(&token)
- .ok()
- .and_then(|data| retrive_user(data.claims.user));
- Ok(user)
- }
- async fn get_user(
- &self,
- user_id: &<Self::User as AuthUser>::Id,
- ) -> Result<Option<Self::User>, Self::Error> {
- Ok(self.users.get(user_id).cloned())
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement