mirror of
https://github.com/teamhanko/hanko.git
synced 2025-11-01 22:28:27 +08:00
docs: move documentation into monorepo
This commit is contained in:
150
docs/docs/guides/angular.mdx
Normal file
150
docs/docs/guides/angular.mdx
Normal file
@ -0,0 +1,150 @@
|
||||
---
|
||||
title: Angular + Hanko
|
||||
sidebar_label: Angular
|
||||
keywords: [angular]
|
||||
sidebar_custom_props:
|
||||
docCardIconName: angular
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Angular
|
||||
|
||||
In this guide you will learn how to add authentication to your Angular application using the Hanko custom element.
|
||||
|
||||
## Install dependencies
|
||||
|
||||
Install the `@teamhanko/hanko-elements` package:
|
||||
|
||||
```shell npm2yarn
|
||||
npm install @teamhanko/hanko-elements
|
||||
```
|
||||
|
||||
## Register custom element with Angular
|
||||
|
||||
Angular requires you to explicitly declare that you are using custom elements inside your Angular modules, otherwise
|
||||
it will fail during build complaining about unknown elements. To do so, import the
|
||||
[`CUSTOM_ELEMENTS_SCHEMA`](https://angular.io/api/core/CUSTOM_ELEMENTS_SCHEMA), and add it to the `schemas` in your
|
||||
module:
|
||||
|
||||
```js {1,14} title="app.module.ts" showLineNumbers
|
||||
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
})
|
||||
export class AppModule { }
|
||||
```
|
||||
|
||||
## Import & use custom element
|
||||
|
||||
Import `@teamhanko/hanko-elements/hanko-auth` in the component where you want to use the Hanko custom element.
|
||||
Doing so registers the `<hanko-auth>` element with the browser's
|
||||
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry). Then use the element
|
||||
in your component template:
|
||||
|
||||
```mdx-code-block
|
||||
<Tabs>
|
||||
<TabItem value="html" label="login.component.html">
|
||||
```
|
||||
|
||||
```html title="login.component.html" showLineNumbers
|
||||
<hanko-auth [api]="hankoApi" [lang]="hankoLang"></hanko-auth>
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
<TabItem value="ts" label="login.component.ts">
|
||||
```
|
||||
|
||||
```js {3,11-12} title="login.component.ts" showLineNumbers
|
||||
import { Component } from '@angular/core';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import '@teamhanko/hanko-elements/hanko-auth';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.css']
|
||||
})
|
||||
export class LoginComponent {
|
||||
hankoApi = environment.hankoApi;
|
||||
hankoLang = environment.hankoLang;
|
||||
}
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Defining login callbacks
|
||||
|
||||
The `<hanko-auth>` element dispatches a custom `success` event on successful login. React to this
|
||||
event in order to, for example, redirect your users to protected pages in your application.
|
||||
|
||||
To do so, you can use Angular's event binding mechanism and supply a callback function that is defined in your component
|
||||
class directly on the `<hanko-auth>` element:
|
||||
|
||||
```mdx-code-block
|
||||
<Tabs>
|
||||
<TabItem value="html" label="login.component.html">
|
||||
```
|
||||
|
||||
```html {2} title="login.component.html" showLineNumbers
|
||||
<hanko-auth
|
||||
(success)="redirectToProfile()"
|
||||
[api]="hankoApi"
|
||||
[lang]="hankoLang">
|
||||
</hanko-auth>
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
<TabItem value="ts" label="login.component.ts">
|
||||
```
|
||||
|
||||
```js {3,15-19} title="login.component.ts" showLineNumbers
|
||||
import { Component } from '@angular/core';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { Router } from '@angular/router';
|
||||
import '@teamhanko/hanko-elements/hanko-auth';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.css'],
|
||||
})
|
||||
export class LoginComponent {
|
||||
hankoApi = environment.hankoApi;
|
||||
hankoLang = environment.hankoLang;
|
||||
|
||||
constructor(private router: Router) {}
|
||||
|
||||
redirectToProfile() {
|
||||
this.router.navigate(['/profile']);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
```
|
||||
|
||||
## Backend request authentication
|
||||
|
||||
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).
|
||||
60
docs/docs/guides/backend.mdx
Normal file
60
docs/docs/guides/backend.mdx
Normal file
@ -0,0 +1,60 @@
|
||||
---
|
||||
sidebar_label: Backend guide
|
||||
sidebar_position: 3
|
||||
description: "Learn how to authenticate requests in your backend by verifying JWTs (JSON Web Token) using a JWK (JSON Web Key Set)."
|
||||
---
|
||||
|
||||
# Backend guide
|
||||
|
||||
After a successful login Hanko issues a cookie containing a JSON Web Token
|
||||
([JWT](https://datatracker.ietf.org/doc/html/rfc7519)). You can use this JWT to authenticate
|
||||
requests on your backend. To do so, first retrieve the JSON Web Key Set
|
||||
([JWKS](https://datatracker.ietf.org/doc/html/rfc7517))
|
||||
containing the public keys used to verify the JSON Web Token (JWT) from the Hanko API's `.well-known/jwks.json` endpoint.
|
||||
Then use the JWKS to verify the JWT using a library for the programming language of your choice.
|
||||
|
||||
The following code shows an example of a custom middleware in a Go-based backend using
|
||||
[Echo](https://echo.labstack.com/) and the [lestrrat-go/jwx](https://github.com/lestrrat-go/jwx) package:
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/lestrrat-go/jwx/v2/jwk"
|
||||
"github.com/lestrrat-go/jwx/v2/jwt"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func SessionMiddleware(hankoUrl string) echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
cookie, err := c.Cookie("hanko")
|
||||
if err == http.ErrNoCookie {
|
||||
return c.Redirect(http.StatusTemporaryRedirect, "/unauthorized")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// replace "hankoApiURL" with your API URL
|
||||
set, err := jwk.Fetch(context.Background(), fmt.Sprintf("%v/.well-known/jwks.json", hankoApiURL))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
token, err := jwt.Parse([]byte(cookie.Value), jwt.WithKeySet(set))
|
||||
if err != nil {
|
||||
return c.Redirect(http.StatusTemporaryRedirect, "/unauthorized")
|
||||
}
|
||||
|
||||
log.Printf("session for user '%s' verified successfully", token.Subject())
|
||||
|
||||
c.Set("token", cookie.Value)
|
||||
c.Set("user", token.Subject())
|
||||
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
105
docs/docs/guides/next.mdx
Normal file
105
docs/docs/guides/next.mdx
Normal file
@ -0,0 +1,105 @@
|
||||
---
|
||||
title: Next.js + Hanko
|
||||
sidebar_label: Next.js
|
||||
keywords: [next, nextjs]
|
||||
sidebar_custom_props:
|
||||
docCardIconName: nextjs-dark
|
||||
---
|
||||
|
||||
# Next.js
|
||||
|
||||
In this guide you will learn how to add authentication to your Next.js application using the Hanko custom element.
|
||||
|
||||
## Install dependencies
|
||||
|
||||
Install the `@teamhanko/hanko-elements` package:
|
||||
|
||||
```shell npm2yarn
|
||||
npm install @teamhanko/hanko-elements
|
||||
```
|
||||
|
||||
## Import & use custom element
|
||||
|
||||
Import `@teamhanko/hanko-elements/hanko-auth` in the component where you want to use the Hanko custom element.
|
||||
|
||||
```jsx title="HankoAuth.jsx" showLineNumbers
|
||||
import "@teamhanko/hanko-elements/hanko-auth";
|
||||
|
||||
export default function HankoAuth() {
|
||||
return (
|
||||
<hanko-auth
|
||||
api={process.env.NEXT_PUBLIC_HANKO_API}
|
||||
lang={process.env.NEXT_PUBLIC_HANKO_LANG}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
If you used this component in your application, the import would attempt to register the `<hanko-auth>` element with the
|
||||
browser's [`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) through a
|
||||
call to `window.customElements.define()`.
|
||||
Next.js pre-renders pages on the server but the browser `window` is not available during pre-rendering, so the custom
|
||||
element registration would fail.
|
||||
|
||||
A solution for this is to use Next's [dynamic import](https://nextjs.org/docs/advanced-features/dynamic-import) feature
|
||||
to dynamically load the component on the client-side and disable server rendering for it:
|
||||
|
||||
```jsx title="index.js" showLineNumbers
|
||||
import dynamic from "next/dynamic";
|
||||
|
||||
export default function Home() {
|
||||
const HankoAuthNoSSR = dynamic(
|
||||
// replace with path to your component using the <hanko-auth> element
|
||||
() => import('../components/HankoAuth'),
|
||||
{ ssr: false },
|
||||
)
|
||||
return (
|
||||
<Suspense fallback={"Loading ..."}>
|
||||
<HankoAuthNoSSR/>
|
||||
</Suspense>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Defining login callbacks
|
||||
|
||||
The `<hanko-auth>` element dispatches a custom `success` event on successful login. React to this
|
||||
event in order to, for example, redirect your users to protected pages in your application.
|
||||
|
||||
To do so, create a [`ref`](https://reactjs.org/docs/hooks-reference.html#useref) to obtain access to the `<hanko-auth>`
|
||||
DOM element and apply an event listener with an appropriate redirect callback:
|
||||
|
||||
```jsx {1-2,6-18,22} title="HankoAuth.jsx" showLineNumbers
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import "@teamhanko/hanko-elements/hanko-auth";
|
||||
|
||||
export default function HankoAuth() {
|
||||
const router = useRouter();
|
||||
const ref = useRef(null);
|
||||
|
||||
const redirectToProfile = () => {
|
||||
router.replace("/profile");
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const { current } = ref;
|
||||
|
||||
current?.addEventListener("success", redirectToProfile);
|
||||
return () => current?.removeEventListener("success", redirectToProfile);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<hanko-auth
|
||||
ref={ref}
|
||||
api={process.env.NEXT_PUBLIC_HANKO_API}
|
||||
lang={process.env.NEXT_PUBLIC_HANKO_LANG}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Backend request authentication
|
||||
|
||||
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).
|
||||
|
||||
82
docs/docs/guides/react.mdx
Normal file
82
docs/docs/guides/react.mdx
Normal file
@ -0,0 +1,82 @@
|
||||
---
|
||||
title: React + Hanko
|
||||
sidebar_label: React
|
||||
keywords: [react]
|
||||
sidebar_custom_props:
|
||||
docCardIconName: react
|
||||
---
|
||||
|
||||
# React
|
||||
|
||||
In this guide you will learn how to add authentication to your React application using the Hanko custom element.
|
||||
|
||||
## Install dependencies
|
||||
Install the `@teamhanko/hanko-elements` package:
|
||||
|
||||
```shell npm2yarn
|
||||
npm install @teamhanko/hanko-elements
|
||||
```
|
||||
|
||||
## Import & use custom element
|
||||
|
||||
Import `@teamhanko/hanko-elements/hanko-auth` in the component where you want to use the Hanko custom element.
|
||||
Doing so registers the `<hanko-auth>` element with the browser's
|
||||
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry). Then use the element
|
||||
in your JSX:
|
||||
|
||||
```jsx {1,4-7} title="HankoAuth.jsx" showLineNumbers
|
||||
import "@teamhanko/hanko-elements/hanko-auth";
|
||||
|
||||
function HankoAuth() {
|
||||
return <hanko-auth
|
||||
api={process.env.NEXT_PUBLIC_HANKO_API}
|
||||
lang={process.env.NEXT_PUBLIC_HANKO_LANG}
|
||||
/>;
|
||||
}
|
||||
|
||||
export default HankoAuth;
|
||||
```
|
||||
|
||||
## Defining login callbacks
|
||||
|
||||
The `<hanko-auth>` element dispatches a custom `success` event on successful login. React to this
|
||||
event in order to, for example, redirect your users to protected pages in your application.
|
||||
|
||||
To do so, create a [`ref`](https://reactjs.org/docs/hooks-reference.html#useref) to obtain access to the `<hanko-auth>`
|
||||
DOM element and apply an event listener with an appropriate redirect callback:
|
||||
|
||||
```jsx {1-2,6-18,22} title="HankoAuth.jsx" showLineNumbers
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import "@teamhanko/hanko-elements/hanko-auth";
|
||||
|
||||
function HankoAuth() {
|
||||
const ref = useRef(null);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const redirectToProfile = () => {
|
||||
navigate("/profile", { replace: true });
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const { current } = ref;
|
||||
|
||||
current?.addEventListener("success", redirectToProfile);
|
||||
return () => current?.removeEventListener("success", redirectToProfile);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<hanko-auth
|
||||
ref={ref}
|
||||
api={process.env.REACT_APP_HANKO_API}
|
||||
lang={process.env.REACT_APP_HANKO_LANG}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default HankoAuth;
|
||||
```
|
||||
|
||||
## Backend request authentication
|
||||
|
||||
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).
|
||||
127
docs/docs/guides/vue.mdx
Normal file
127
docs/docs/guides/vue.mdx
Normal file
@ -0,0 +1,127 @@
|
||||
---
|
||||
title: Vue + Hanko
|
||||
sidebar_label: Vue
|
||||
keywords: [vue]
|
||||
sidebar_custom_props:
|
||||
docCardIconName: vue
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Vue
|
||||
|
||||
In this guide you will learn how to add authentication to your Vue application using the Hanko custom element.
|
||||
|
||||
## Install dependencies
|
||||
|
||||
Install the `@teamhanko/hanko-elements` package:
|
||||
|
||||
```shell npm2yarn
|
||||
npm install @teamhanko/hanko-elements
|
||||
```
|
||||
|
||||
## Register custom element with Vue
|
||||
|
||||
Vue needs to know which elements to treat as custom elements, otherwise it will issue a warning regarding component
|
||||
resolution. To do so, provide a predicate function that determines which elements are to be considered custom elements
|
||||
to `compilerOptions.isCustomElement` in your configuration:
|
||||
|
||||
```mdx-code-block
|
||||
<Tabs>
|
||||
<TabItem value="vite" label="Vite Config">
|
||||
```
|
||||
|
||||
```js {7-9} title="vite.config.js" showLineNumbers
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default {
|
||||
plugins: [
|
||||
vue({
|
||||
template: {
|
||||
compilerOptions: {
|
||||
isCustomElement: (tag) => tag === "hanko-auth"
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
<TabItem value="cli" label="Vue CLI Config">
|
||||
```
|
||||
|
||||
```js {8-10} title="vue.config.js" showLineNumbers
|
||||
module.exports = {
|
||||
chainWebpack: config => {
|
||||
config.module
|
||||
.rule('vue')
|
||||
.use('vue-loader')
|
||||
.tap(options => ({
|
||||
...options,
|
||||
compilerOptions: {
|
||||
isCustomElement: (tag) => tag === "hanko-auth"
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```mdx-code-block
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
```
|
||||
|
||||
## Import & use custom element
|
||||
|
||||
Import `@teamhanko/hanko-elements/hanko-auth` in the component where you want to use the Hanko custom element.
|
||||
Doing so registers the `<hanko-auth>` element with the browser's
|
||||
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry). Then use the
|
||||
element in your component template:
|
||||
|
||||
```js title="HankoAuth.vue" showLineNumbers
|
||||
<script setup>
|
||||
import "@teamhanko/hanko-elements/hanko-auth";
|
||||
|
||||
const api = import.meta.env.VITE_HANKO_API;
|
||||
const lang = import.meta.env.VITE_HANKO_LANG;
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<hanko-auth :api="api" :lang="lang" />
|
||||
</template>
|
||||
```
|
||||
|
||||
## Defining login callbacks
|
||||
|
||||
The `<hanko-auth>` element dispatches a custom `success` event on successful login. React to this
|
||||
event in order to, for example, redirect your users to protected pages in your application.
|
||||
|
||||
To do so, you can use Vue's [`v-on`](https://vuejs.org/guide/essentials/event-handling.html#listening-to-events)
|
||||
directive (shorthand: `@`) and supply a callback directly on the `<hanko-auth>` element:
|
||||
|
||||
```js {2,8-12,16} title="HankoAuth.vue" showLineNumbers
|
||||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import "@teamhanko/hanko-elements/hanko-auth";
|
||||
|
||||
const api = import.meta.env.VITE_HANKO_API;
|
||||
const lang = import.meta.env.VITE_HANKO_LANG;
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const redirectToProfile = () => {
|
||||
router.push({ path: "/profile" });
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<hanko-auth @success="redirectToProfile" :api="api" :lang="lang" />
|
||||
</template>
|
||||
```
|
||||
|
||||
## Backend request authentication
|
||||
|
||||
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).
|
||||
21
docs/docs/intro.md
Normal file
21
docs/docs/intro.md
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
slug: /
|
||||
title: Introduction
|
||||
---
|
||||
# :wave: Welcome to Hanko Docs
|
||||
Hanko is a lightweight, open source user authentication solution that takes you on the journey beyond passwords. For better security, increased conversion rates, and happier users.
|
||||
|
||||
## Get started with Hanko
|
||||
To get started with Hanko, visit the [Hanko project](https://github.com/teamhanko/hanko) on GitHub and follow the instructions to get Hanko up and running locally.
|
||||
|
||||
## Integrate Hanko
|
||||
To integrate Hanko into your project, we are providing [guides](/guides/frontend) for popular frontend frameworks.
|
||||
|
||||
## Give feedback
|
||||
We'd love to hear your thoughts about Hanko, especially if you encounter any problems. Please do not hesitate to reach out. You can find us on
|
||||
- [Hanko Community Slack](https://www.hanko.io/community)
|
||||
- [Twitter](https://twitter.com/hanko_io)
|
||||
|
||||
## Contribute
|
||||
Contributions to the Hanko project are appreciated. For more complex topics, we encourage you to talk to us first to avoid misunderstandings. We're actively working on Hanko and may have already started implementing certain features.
|
||||
Reference in New Issue
Block a user