implement auth login with a JWT cookie
This commit is contained in:
parent
b5a71c87ad
commit
84bffc5f72
6 changed files with 86 additions and 6 deletions
|
@ -8,7 +8,10 @@ Login
|
|||
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
<img class="mx-auto h-12 w-auto" src="https://nixin.distrilab.eu/logo-nixin.svg" alt="NixiN">
|
||||
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">Index</h2>
|
||||
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">
|
||||
Index
|
||||
</h2>
|
||||
hello user {{user.name}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -34,7 +34,7 @@ Login
|
|||
</div>
|
||||
|
||||
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
<form class="space-y-6" action="#" method="POST">
|
||||
<form class="space-y-6" action="/login" method="POST">
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium leading-6 text-gray-900">Email address</label>
|
||||
<div class="mt-2">
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}
|
||||
Login
|
||||
{% endblock title %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
|
||||
<div class="sm:mx-auto sm:w-full sm:max-w-sm">
|
||||
<img class="mx-auto h-12 w-auto" src="https://nixin.distrilab.eu/logo-nixin.svg" alt="NixiN">
|
||||
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">
|
||||
Register a new account
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock content %}
|
|
@ -146,3 +146,6 @@ auth:
|
|||
secret: jECGaGSsMtQmKyYyGuk7
|
||||
# Token expiration time in seconds
|
||||
expiration: 604800 # 7 days
|
||||
location:
|
||||
from: Cookie
|
||||
name: token
|
||||
|
|
|
@ -2,8 +2,18 @@
|
|||
#![allow(clippy::unnecessary_struct_initialization)]
|
||||
#![allow(clippy::unused_async)]
|
||||
use loco_rs::prelude::*;
|
||||
use axum::debug_handler;
|
||||
use axum::{extract::State, Json};
|
||||
|
||||
use axum::{
|
||||
debug_handler,
|
||||
extract::State,
|
||||
extract::Query,
|
||||
response::{IntoResponse, Redirect},
|
||||
http::StatusCode,
|
||||
Json,
|
||||
Form};
|
||||
use axum_extra::extract::cookie::{CookieJar, Cookie};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use loco_rs::{
|
||||
app::AppContext,
|
||||
controller::middleware,
|
||||
|
@ -11,7 +21,10 @@ use loco_rs::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
models::users,
|
||||
models::{
|
||||
users,
|
||||
//users::{LoginParams, RegisterParams},
|
||||
},
|
||||
views,
|
||||
controllers::middleware::auth_no_error,
|
||||
};
|
||||
|
@ -36,8 +49,52 @@ pub async fn home(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct LoginParams {
|
||||
pub email: Option<String>,
|
||||
pub password: Option<String>,
|
||||
}
|
||||
|
||||
/// Creates a user login and returns a token
|
||||
#[debug_handler]
|
||||
pub async fn login(
|
||||
auth: auth_no_error::JWTWithUserOpt<users::Model>,
|
||||
//ViewEngine(v): ViewEngine<TeraView>,
|
||||
State(ctx): State<AppContext>,
|
||||
jar: CookieJar,
|
||||
Form(params): Form<LoginParams>) -> Result<(CookieJar, Redirect), StatusCode> {
|
||||
println!("Auth: {:?}",auth);
|
||||
println!("Form parameters: {:?}",params);
|
||||
println!("Cookie jar: {:?}",jar);
|
||||
|
||||
match params {
|
||||
LoginParams{email: Some(email), password: Some(password)} => {
|
||||
let user = users::Model::find_by_email(&ctx.db, &email).await
|
||||
.or_else(|_| Err(StatusCode::UNAUTHORIZED))?;
|
||||
let valid = user.verify_password(&password);
|
||||
if !valid {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
let jwt_secret = ctx.config.get_jwt_config()
|
||||
.or_else(|_| Err(StatusCode::UNAUTHORIZED))?;
|
||||
let token = user
|
||||
.generate_jwt(&jwt_secret.secret, &jwt_secret.expiration)
|
||||
.or_else(|_| Err(StatusCode::UNAUTHORIZED))?;
|
||||
Ok((
|
||||
// the updated jar must be returned for the changes
|
||||
// to be included in the response
|
||||
jar.add(Cookie::new("token", token)),
|
||||
Redirect::to("/"),))
|
||||
}
|
||||
_ => {
|
||||
Err(StatusCode::UNAUTHORIZED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn routes() -> Routes {
|
||||
Routes::new()
|
||||
//.prefix("homes")
|
||||
.add("/", get(home))
|
||||
.add("/login", post(login))
|
||||
}
|
||||
|
|
|
@ -17,6 +17,6 @@ pub fn login(v: &impl ViewRenderer) -> Result<Response> {
|
|||
///
|
||||
/// When there is an issue with rendering the view.
|
||||
pub fn index(v: &impl ViewRenderer, user: &users::Model) -> Result<Response> {
|
||||
format::render().view(v, "server/show.html", data!({"user": user}))
|
||||
format::render().view(v, "home/index.html", data!({"user": user}))
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue