Expand description
Protect parts of your Leptos application using Keycloak.
§Example
use leptos::prelude::*;
use leptos_router::path;
use leptos_router::components::*;
use leptos_keycloak_auth::{to_current_url, init_keycloak_auth, Authenticated, KeycloakAuth, UseKeycloakAuthOptions, ValidationOptions};
use leptos_keycloak_auth::components::*;
use leptos_keycloak_auth::url::Url;
#[component]
pub fn Init(children: Children) -> impl IntoView {
// Note: These values should be served from environment variables to be overwritten in production.
// Note: Redirect URLs should match the route path at which you render this component.
// If this component is rendered at `/admin`, the redirects should also go to that route,
// or we end up in a place where `use_keycloak_auth` is not rendered/active
// and any login attempt can never be completed.
// Using `to_current_url()` allows us to render `<Protected>` anywhere we want.
let keycloak_server_url = "http://localhost:8443".to_owned();
let _auth = init_keycloak_auth(UseKeycloakAuthOptions {
keycloak_server_url: Url::parse(&keycloak_server_url).unwrap(),
realm: "test-realm".to_owned(),
client_id: "test-client".to_owned(),
post_login_redirect_url: to_current_url(),
post_logout_redirect_url: to_current_url(),
scope: vec![],
id_token_validation: ValidationOptions {
expected_audiences: Some(vec!["test-client".to_owned()]),
expected_issuers: Some(vec![format!("{keycloak_server_url}/realms/test-realm")]),
},
delay_during_hydration: true,
advanced: Default::default(),
});
children()
}
#[component]
pub fn App() -> impl IntoView {
// Meta tags excluded...
view! {
<main>
<Router>
<Init>
<Routes fallback=|| view! { "Page not found." }>
<Route path=path!("/") view=|| view! {
<Protected>
<ConfidentialArea/>
</Protected>
}/>
</Routes>
</Init>
</Router>
</main>
}
}
#[component]
pub fn Protected(children: ChildrenFn) -> impl IntoView {
view! {
<ShowWhenAuthenticated fallback=|| view! { <Login/> }>
{ children() }
</ShowWhenAuthenticated>
}
}
#[component]
pub fn Login() -> impl IntoView {
let auth = expect_context::<KeycloakAuth>();
let login_url_unavailable = Signal::derive(move || auth.login_url.get().is_none());
let login_url = Signal::derive(move || {
auth.login_url
.get()
.map(|url| url.to_string())
.unwrap_or_default()
});
view! {
<h1>"Unauthenticated"</h1>
<a href=move || login_url.get() aria_disabled=login_url_unavailable>
"Log in"
</a>
}
}
#[component]
pub fn ConfidentialArea() -> impl IntoView {
// We can expect this context, as we only render this component under `ShowWhenAuthenticated`.
// It gives direct access to the users decoded ID token.
let auth = expect_context::<Authenticated>();
view! {
<div>
"Hello, " { move || auth.id_token_claims.read().name.clone() }
</div>
}
}
Modules§
Structs§
- Advanced
Options - Authenticated
- State only accessible when the user is authenticated.
- Authenticated
Client - Keycloak
Auth - The global state this library tracks for you. Gives access to
login_url
andlogout_url
as well as the current authenticationstate
. - NotAuthenticated
- UseKeycloak
Auth Options - Represents authentication parameters required for initializing the
Auth
structure. These parameters include authentication and token endpoints, client ID, and other related data. - Validation
Options
Enums§
- Keycloak
Auth State - The current state of authentication.
- Life
Left - Request
Action - Storage
Type - Local or session storage or a custom store that is a
web_sys::Storage
.
Functions§
- expect_
authenticated - Get access to the current user data.
- expect_
keycloak_ auth - Get access to the current authentication state.
- init_
keycloak_ auth - Initializes a new
KeycloakAuth
instance, the authentication handler responsible for handling user authentication and token management, with the provided authentication parameters. - to_
current_ url - to_
current_ url_ untracked