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::session::{self, UserSession};
use crate::{models::WebApiLoginRequest, AppState}; use crate::{models::WebApiLoginRequest, AppState};
use axum::extract::Path; use axum::extract::Path;
use axum::http::{status, HeaderMap, HeaderValue}; use axum::http::{status, HeaderMap};
use axum::response::Result; use axum::response::Result;
use axum::routing::delete; use axum::routing::delete;
use axum::Form; use axum::Form;
@ -99,22 +99,13 @@ pub async fn change_password_handler(
Ok(WebApiResponse::<()>::from_str("Password changed".into())) 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( pub async fn post_oauth_login_handler(
header_map: HeaderMap, header_map: HeaderMap,
Path(provider): Path<String>, Path(provider): Path<String>,
) -> Result<WebApiResponse<String>, WebApiError<'static>> { ) -> Result<WebApiResponse<String>, WebApiError<'static>> {
let host = header_map let scheme = get_header_value_or_default(&header_map, "x-scheme", "http");
.get("host") let host = get_header_value_or_default(&header_map, "host", "localhost");
.unwrap_or(&DEFAULT_HOST)
.to_str()
.unwrap();
let scheme = header_map
.get("x-scheme")
.unwrap_or(&DEFAULT_SCHEME)
.to_str()
.unwrap();
let base_url = format!("{}://{}", scheme, host); let base_url = format!("{}://{}", scheme, host);
let redirect_uri = format!("{}/web/oauth_login_redirect", base_url); 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()) 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( pub async fn admin_update_user_handler(
State(state): State<AppState>, State(state): State<AppState>,
session: UserSession, session: UserSession,
@ -226,6 +234,7 @@ pub async fn login_refresh_handler(
// sign up if not exist // sign up if not exist
pub async fn login_handler( pub async fn login_handler(
State(state): State<AppState>, State(state): State<AppState>,
header_map: HeaderMap,
jar: CookieJar, jar: CookieJar,
Form(param): Form<WebApiLoginRequest>, Form(param): Form<WebApiLoginRequest>,
) -> Result<(CookieJar, HeaderMap, WebApiResponse<()>), WebApiError<'static>> { ) -> Result<(CookieJar, HeaderMap, WebApiResponse<()>), WebApiError<'static>> {
@ -252,7 +261,15 @@ pub async fn login_handler(
("invalid_grant", Some("Invalid login credentials")) => { ("invalid_grant", Some("Invalid login credentials")) => {
let sign_up_res = state let sign_up_res = state
.gotrue_client .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; .await;
match sign_up_res { match sign_up_res {

View File

@ -52,12 +52,28 @@ impl Client {
#[tracing::instrument(skip_all, err)] #[tracing::instrument(skip_all, err)]
pub async fn sign_up(&self, email: &str, password: &str) -> Result<SignUpResponse, GoTrueError> { 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!({ let payload = serde_json::json!({
"email": email, "email": email,
"password": password, "password": password,
}); });
let url: String = format!("{}/signup", self.base_url); 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 to_gotrue_result(resp).await
} }

View File

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