feat: redirect to web if login from web

This commit is contained in:
Fu Zi Xiang 2023-11-22 13:25:51 +08:00
parent 61527f723b
commit b934664b8c
No known key found for this signature in database
3 changed files with 67 additions and 33 deletions

View File

@ -7,7 +7,7 @@ use crate::response::WebApiResponse;
use crate::session::{self, UserSession};
use crate::{models::WebApiLoginRequest, AppState};
use axum::extract::Path;
use axum::http::{status, HeaderMap, HeaderValue};
use axum::http::{status, HeaderMap};
use axum::response::Result;
use axum::routing::delete;
use axum::Form;
@ -99,22 +99,13 @@ pub async fn change_password_handler(
Ok(WebApiResponse::<()>::from_str("Password changed".into()))
}
static DEFAULT_HOST: HeaderValue = HeaderValue::from_static("localhost");
static DEFAULT_SCHEME: HeaderValue = HeaderValue::from_static("http");
pub async fn post_oauth_login_handler(
header_map: HeaderMap,
Path(provider): Path<String>,
) -> Result<WebApiResponse<String>, WebApiError<'static>> {
let host = header_map
.get("host")
.unwrap_or(&DEFAULT_HOST)
.to_str()
.unwrap();
let scheme = header_map
.get("x-scheme")
.unwrap_or(&DEFAULT_SCHEME)
.to_str()
.unwrap();
let scheme = get_header_value_or_default(&header_map, "x-scheme", "http");
let host = get_header_value_or_default(&header_map, "host", "localhost");
let base_url = format!("{}://{}", scheme, host);
let redirect_uri = format!("{}/web/oauth_login_redirect", base_url);
@ -125,6 +116,23 @@ pub async fn post_oauth_login_handler(
Ok(oauth_url.into())
}
fn get_header_value_or_default<'a>(
header_map: &'a HeaderMap,
header_name: &str,
default: &'a str,
) -> &'a str {
match header_map.get(header_name) {
Some(v) => match v.to_str() {
Ok(v) => v,
Err(e) => {
tracing::error!("failed to get header value {}: {}, {:?}", header_name, e, v);
default
},
},
None => default,
}
}
pub async fn admin_update_user_handler(
State(state): State<AppState>,
session: UserSession,
@ -226,6 +234,7 @@ pub async fn login_refresh_handler(
// sign up if not exist
pub async fn login_handler(
State(state): State<AppState>,
header_map: HeaderMap,
jar: CookieJar,
Form(param): Form<WebApiLoginRequest>,
) -> Result<(CookieJar, HeaderMap, WebApiResponse<()>), WebApiError<'static>> {
@ -252,7 +261,15 @@ pub async fn login_handler(
("invalid_grant", Some("Invalid login credentials")) => {
let sign_up_res = state
.gotrue_client
.sign_up(&param.email, &param.password)
.sign_up_with_referrer(
&param.email,
&param.password,
Some(get_header_value_or_default(
&header_map,
"host",
"localhost",
)),
)
.await;
match sign_up_res {

View File

@ -52,12 +52,28 @@ impl Client {
#[tracing::instrument(skip_all, err)]
pub async fn sign_up(&self, email: &str, password: &str) -> Result<SignUpResponse, GoTrueError> {
self.sign_up_with_referrer(email, password, None).await
}
#[tracing::instrument(skip_all, err)]
pub async fn sign_up_with_referrer(
&self,
email: &str,
password: &str,
redirect_to: Option<&str>,
) -> Result<SignUpResponse, GoTrueError> {
let payload = serde_json::json!({
"email": email,
"password": password,
});
let url: String = format!("{}/signup", self.base_url);
let resp = self.client.post(&url).json(&payload).send().await?;
let mut req_builder = self.client.post(&url).json(&payload);
if let Some(redirect_to) = redirect_to {
req_builder = req_builder.header("redirect_to", redirect_to);
}
let resp = req_builder.send().await?;
to_gotrue_result(resp).await
}

View File

@ -37,6 +37,7 @@ http {
# Allow headers like redirect_to to be handed over to the gotrue
# for correct redirecting
proxy_set_header Host $http_host;
proxy_pass_request_headers on;
}
@ -59,29 +60,29 @@ http {
# Minio Web UI
# Derive from: https://min.io/docs/minio/linux/integrations/setup-nginx-proxy-with-minio.html
location /minio/ {
rewrite ^/minio/(.*) /$1 break;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
rewrite ^/minio/(.*) /$1 break;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-NginX-Proxy true;
## This is necessary to pass the correct IP to be hashed
real_ip_header X-Real-IP;
## This is necessary to pass the correct IP to be hashed
real_ip_header X-Real-IP;
proxy_connect_timeout 300;
proxy_connect_timeout 300;
## To support websockets in MinIO versions released after January 2023
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)
# Uncomment the following line to set the Origin request to an empty string
# proxy_set_header Origin '';
## To support websockets in MinIO versions released after January 2023
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)
# Uncomment the following line to set the Origin request to an empty string
# proxy_set_header Origin '';
chunked_transfer_encoding off;
chunked_transfer_encoding off;
proxy_pass http://minio:9001;
proxy_pass http://minio:9001;
}
# PgAdmin