@auth/sveltekit
@auth/sveltekit
は現在実験段階です。APIは変更される可能性があります。
SvelteKit Authは、Auth.jsの公式SvelteKit統合です。数行のコードでSvelteKitアプリに認証を追加する簡単な方法を提供します。
インストール
npm install @auth/sveltekit
使用方法
import { SvelteKitAuth } from "@auth/sveltekit"
import GitHub from "@auth/sveltekit/providers/github"
export const { handle, signIn, signOut } = SvelteKitAuth({
providers: [GitHub],
})
遅延初期化
@auth/sveltekit
は、event
オブジェクトを読み取って構成を遅延設定できる遅延初期化をサポートしています。これは、Cloudflare Workersなどのプラットフォームでevent.platform
から環境変数を取得する必要がある場合に特に役立ちます。
import { SvelteKitAuth } from "@auth/sveltekit"
import GitHub from "@auth/sveltekit/providers/github"
export const { handle, signIn, signOut } = SvelteKitAuth(async (event) => {
const authOptions = {
providers: [
GitHub({
clientId: event.platform.env.AUTH_GITHUB_ID,
clientSecret: event.platform.env.AUTH_GITHUB_SECRET
})
],
secret: event.platform.env.AUTH_SECRET,
trustHost: true
}
return authOptions
})
src/hooks.server.ts
でhandleを再エクスポートします。
export { handle } from "./auth"
AUTH_SECRET
環境変数を設定することを忘れないでください。これは、最低32文字のランダムな文字列にする必要があります。UNIXシステムではopenssl rand -hex 32
を使用するか、https://generate-secret.vercel.app/32
をご覧ください。
Vercel以外でアプリをデプロイする場合は、Cloudflare PagesやNetlifyなどの他のホスティングプロバイダーのために、AUTH_TRUST_HOST
変数をtrue
に設定します。
プロバイダーで使用されるコールバックURLは、SvelteKitAuthConfig.basePathをオーバーライドしない限り、次のものにする必要があります。
[origin]/auth/callback/[provider]
サインインとサインアウト
サーバーサイド
<SignIn />
と<SignOut />
は@auth/sveltekit
がすぐに提供するコンポーネントです。これらはサインイン/サインアウトフローを処理し、出発点としてそのまま使用したり、独自のコンポーネントに合わせてカスタマイズしたりできます。これは、SvelteKitのサーバーサイドフォームアクションを使用してログインおよびログアウトするためのSignIn
およびSignOut
コンポーネントの使用方法の例です。これを実現するには、2つのものが必要です。
- SvelteKitアプリのフロントエンドでコンポーネントを使用する
- フォームアクションを処理するために、必要な
page.server.ts
を/signin
(SignIn
用)および/signout
(SignOut
用)に追加します。
<script>
import { SignIn, SignOut } from "@auth/sveltekit/components"
import { page } from "$app/stores"
</script>
<h1>SvelteKit Auth Example</h1>
<div>
{#if $page.data.session}
{#if $page.data.session.user?.image}
<img
src={$page.data.session.user.image}
class="avatar"
alt="User Avatar"
/>
{/if}
<span class="signedInText">
<small>Signed in as</small><br />
<strong>{$page.data.session.user?.name ?? "User"}</strong>
</span>
<SignOut>
<div slot="submitButton" class="buttonPrimary">Sign out</div>
</SignOut>
{:else}
<span class="notSignedInText">You are not signed in</span>
<SignIn>
<div slot="submitButton" class="buttonPrimary">Sign in</div>
</SignIn>
<SignIn provider="facebook"/>
{/if}
</div>
フォームアクションを設定するには、src/routes
にファイルを定義する必要があります。
import { signIn } from "../../auth"
import type { Actions } from "./$types"
export const actions: Actions = { default: signIn }
import { signOut } from "../../auth"
import type { Actions } from "./$types"
export const actions: Actions = { default: signOut }
これらのルートは、それぞれのコンポーネントのsignInPage
およびsignOutPage
プロップを使用してカスタマイズできます。
クライアントサイド
クライアント側のサインインとサインアウトアクションを実行するために、@auth/sveltekit/client
から2つのメソッドもエクスポートします。
import { signIn, signOut } from "@auth/sveltekit/client"
<nav>
<p>
These actions are all using the methods exported from
<code>@auth/sveltekit/client</code>
</p>
<div class="actions">
<div class="wrapper-form">
<button on:click={() => signIn("github")}>Sign In with GitHub</button>
</div>
<div class="wrapper-form">
<button on:click={() => signIn("discord")}>Sign In with Discord</button>
</div>
<div class="wrapper-form">
<div class="input-wrapper">
<label for="password">Password</label>
<input
bind:value={password}
type="password"
id="password"
name="password"
required
/>
</div>
<button on:click={() => signIn("credentials", { password })}>
Sign In with Credentials
</button>
<button on:click={() => signOut()})}>
Sign Out
</button>
</div>
</div>
</nav>
セッションの管理
上記の例では、$page.data.session
にセッションが存在するかどうかをチェックしていますが、これはどこかで私たちが設定する必要があります。このデータをすべてのルートで使用できるようにするには、src/routes/+layout.server.ts
に以下のコードを追加します。次のコードは、すべてのルートで使用可能なように、$page
ストアにセッションデータを設定します。
import type { LayoutServerLoad } from './$types';
export const load: LayoutServerLoad = async (event) => {
return {
session: await event.locals.auth()
};
};
LayoutServerLoad
関数で返すものは、$page
ストアの data
プロパティ内、つまり $page.data
で使用できます。この場合、'session' プロパティを持つオブジェクトを返し、他のコードパスでアクセスしているのがこのプロパティです。
認証処理
SvelteKitでは、認証されていないユーザーからルートを保護する方法はいくつかあります。
コンポーネントごと
最も簡単なケースは、単一ページを保護する場合です。この場合、ロジックを +page.server.ts
ファイルに記述する必要があります。この場合、`await event.parent` を使用してそこからセッションを取得することもできますが、ルートの +layout.server.ts
で上記の処理を行っていなくても、この実装は機能します。
import { redirect } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async (event) => {
const session = await event.locals.auth();
if (!session?.user) throw redirect(303, '/auth');
return {};
};
PageLoad
の場合、ストアを使用する代わりに、常に親からセッション情報を取得してください。そうしないと、+layout.server.ts
がそのページ読み込みで実行されない場合、ユーザーが不正に保護された情報にアクセスできる可能性があります。このコードサンプルでは、const { session } = await parent();
を使用することで、正しい方法が既に実装されています。SvelteKitのload
機能の動作とその認証への影響の詳細については、このSvelteKit ドキュメントセクションを参照してください。
+layout.server.ts
に認証ロジックを記述しないでください。ロジックがツリーの葉に伝播するとは限りません。間違いを避けるために、+page.server.ts
ファイルを使用して各ルートを手動で保護することをお勧めします。レイアウトファイルですべてのルートでロード関数を強制的に実行することは可能ですが、それは変化する可能性があり、簡単にチェックできない特定の動作に依存します。これらの注意点の詳細については、SvelteKitリポジトリのこの問題を参照してください。https://github.com/sveltejs/kit/issues/6315
パスごと
認証を処理するもう1つの方法は、特定のURIへのアクセスを制限することです。多くのプロジェクトでは、これが優れています。
- これにより、これらのURI内のアクションとAPIルートが自動的に保護されます。
- コンポーネント間のコードの重複はありません。
- 変更が非常に簡単です。
URIを介して認証を処理する方法は、handleフックをオーバーライドすることです。src/auth.ts
の SvelteKitAuth
から返される handleフックは、SvelteKit Webアプリに送信されるすべてのリクエストを受け取るように設計された関数です。src/auth.ts
からエクスポートし、src/hooks.server.ts
にインポートする必要があります。src/hooks.server.ts
で複数のハンドルを使用するには、SvelteKitのsequence
を使用して、すべてを順番に実行できます。
import { SvelteKitAuth } from '@auth/sveltekit';
import GitHub from '@auth/sveltekit/providers/github';
export const { handle, signIn, signOut } = SvelteKitAuth({
providers: [GitHub]
}),
import { redirect, type Handle } from '@sveltejs/kit';
import { handle as authenticationHandle } from './auth';
import { sequence } from '@sveltejs/kit/hooks';
async function authorizationHandle({ event, resolve }) {
// Protect any routes under /authenticated
if (event.url.pathname.startsWith('/authenticated')) {
const session = await event.locals.auth();
if (!session) {
// Redirect to the signin page
throw redirect(303, '/auth/signin');
}
}
// If the request is still here, just proceed as normally
return resolve(event);
}
// First handle authentication, then authorization
// Each function acts as a middleware, receiving the request handle
// And returning a handle which gets passed to the next function
export const handle: Handle = sequence(authenticationHandle, authorizationHandle)
SvelteKitのhandleフックとsequenceの詳細についてはこちらを参照してください。
これで、/authenticated
の下にあるすべてのルートは、handleフックによって透過的に保護されます。シーケンスにさらにミドルウェアのような関数を追加し、このファイル内にさらに複雑な認証ビジネスロジックを実装することもできます。これは、特定のページを保護する必要がある場合に、コンポーネントベースのアプローチと併用することもでき、URIによる保護が不適切な場合にも役立ちます。
備考
prerender
を有効にしてSvelteKitアプリケーションをビルドする場合、デフォルトのサインインページへのアンカータグを持つページ(例:<a href="/auth/signin" ...
)はビルドに問題があります。代わりに、組み込み関数またはコンポーネントを使用してサインインまたはサインアウトしてください。
@auth/sveltekit
の詳細についてはこちらを参照してください。
SvelteKitAuthConfig
SvelteKitAuthConfig を再エクスポート
AuthError
すべてのAuth.jsエラーの基本エラークラスです。logger.error
オプションを介して、サーバーログに適切にフォーマットされた方法で出力されるように最適化されています。
拡張
コンストラクタ
new AuthError(message, errorOptions)
new AuthError(message?, errorOptions?): AuthError
パラメータ
パラメータ | 型 |
---|---|
message ? | string | ErrorOptions |
errorOptions ? | ErrorOptions |
戻り値
オーバーライド
Error.constructor
プロパティ
cause?
optional cause: Record<string, unknown> & {
err: Error;
};
型宣言
err?
optional err: Error;
オーバーライド
Error.cause
message
message: string;
継承元
Error.message
name
name: string;
継承元
Error.name
stack?
optional stack: string;
継承元
Error.stack
type
type: ErrorType;
エラーの種類。ログでエラーを識別するために使用されます。
prepareStackTrace()?
static optional prepareStackTrace: (err, stackTraces) => any;
スタックトレースのフォーマットをオーバーライドするためのオプション
参照
https://v8.dokyumento.jp/docs/stack-trace-api#customizing-stack-traces
パラメータ
パラメータ | 型 |
---|---|
err | Error |
stackTraces | CallSite [] |
戻り値
any
継承元
Error.prepareStackTrace
stackTraceLimit
static stackTraceLimit: number;
継承元
Error.stackTraceLimit
メソッド
captureStackTrace()
static captureStackTrace(targetObject, constructorOpt?): void
ターゲットオブジェクトに .stack プロパティを作成します。
パラメータ
パラメータ | 型 |
---|---|
targetObject | object |
constructorOpt ? | Function |
戻り値
void
継承元
Error.captureStackTrace
CredentialsSignin
Credentialsプロバイダーのauthorize
コールバックからスローできます。authorize
コールバックでエラーが発生すると、2つのことが起こります。
- ユーザーは、URLに
error=CredentialsSignin&code=credentials
が含まれたサインインページにリダイレクトされます。code
は設定可能です。 - フォームアクションをサーバーサイドで処理するフレームワークでこのエラーをスローした場合、ユーザーをリダイレクトする代わりにこのエラーがスローされるため、処理する必要があります。
拡張
コンストラクタ
new CredentialsSignin(message, errorOptions)
new CredentialsSignin(message?, errorOptions?): CredentialsSignin
パラメータ
パラメータ | 型 |
---|---|
message ? | string | ErrorOptions |
errorOptions ? | ErrorOptions |
戻り値
継承元
プロパティ
原因
optional cause: Record<string, unknown> & {
err: Error;
};
型宣言
err
optional err: Error;
継承元
コード
code: string;
リダイレクトURLのcode
クエリパラメータに設定されているエラーコードです。
⚠ 注意: このプロパティはURLに含まれるため、機密性の高いエラーを示唆するような情報を含めないようにしてください。
デバッグが必要な場合は、完全なエラーログが常にサーバーに記録されます。
一般的に、ユーザー名またはパスワードが間違っていたかどうかを具体的に示唆することはお勧めしません。「無効な資格情報」などを使用してください。
メッセージ
message: string;
継承元
名前
name: string;
継承元
スタックトレース
optional stack: string;
継承元
型
type: ErrorType;
エラーの種類。ログでエラーを識別するために使用されます。
継承元
種類
static kind: string;
継承元
prepareStackTrace()
static optional prepareStackTrace: (err, stackTraces) => any;
スタックトレースのフォーマットをオーバーライドするためのオプション
参照
https://v8.dokyumento.jp/docs/stack-trace-api#customizing-stack-traces
パラメータ
パラメータ | 型 |
---|---|
err | Error |
stackTraces | CallSite [] |
戻り値
any
継承元
stackTraceLimit
static stackTraceLimit: number;
継承元
型
static type: string;
メソッド
captureStackTrace()
static captureStackTrace(targetObject, constructorOpt?): void
ターゲットオブジェクトに .stack プロパティを作成します。
パラメータ
パラメータ | 型 |
---|---|
targetObject | object |
constructorOpt ? | Function |
戻り値
void
継承元
アカウント
通常、使用されているプロバイダーに関する情報が含まれ、OAuthプロバイダーによって返されるさまざまなトークンであるTokenSet
を拡張しています。
拡張元
Partial
<TokenEndpointResponse
>
プロパティ
access_token
optional readonly access_token: string;
継承元
Partial.access_token
authorization_details
optional readonly authorization_details: AuthorizationDetails[];
継承元
Partial.authorization_details
expires_at
optional expires_at: number;
TokenEndpointResponse.expires_inに基づいて計算された値です。
TokenEndpointResponse.access_tokenが期限切れになる絶対タイムスタンプ(秒単位)です。
この値は、TokenEndpointResponse.refresh_tokenと共にトークンローテーションを実装するために使用できます。
参照
- https://authjs.dokyumento.jp/guides/refresh-token-rotation#database-strategy
- https://www.rfc-editor.org/rfc/rfc6749#section-5.1
expires_in
optional readonly expires_in: number;
継承元
Partial.expires_in
id_token
optional readonly id_token: string;
継承元
Partial.id_token
プロバイダー
provider: string;
このアカウントのプロバイダーIDです。例:「google」。完全なリストはhttps://authjs.dokyumento.jp/reference/core/providersを参照してください。
providerAccountId
providerAccountId: string;
この値は、アカウントの作成に使用されているプロバイダーの種類によって異なります。
- oauth/oidc:
profile()
コールバックから返されるOAuthアカウントのIDです。 - email: ユーザーのメールアドレスです。
- credentials:
authorize()
コールバックから返されるid
です。
refresh_token
optional readonly refresh_token: string;
継承元
Partial.refresh_token
scope
optional readonly scope: string;
継承元
Partial.scope
token_type
optional readonly token_type: Lowercase<string>;
注意: 値は大文字と小文字を区別しないため、常に小文字で返されます。
継承元
Partial.token_type
型
type: ProviderType;
このアカウントのプロバイダーの種類です。
userId
optional userId: string;
このアカウントが属するユーザーのIDです。
参照
https://authjs.dokyumento.jp/reference/core/adapters#adapteruser
DefaultSession
拡張先
プロパティ
有効期限
expires: string;
ユーザー
optional user: User;
プロフィール
OAuthプロバイダーから返されるユーザー情報です。
参照
https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
インデックス可能
[claim
: string
]: unknown
プロパティ
住所
optional address: null | {
country: null | string;
formatted: null | string;
locality: null | string;
postal_code: null | string;
region: null | string;
street_address: null | string;
};
生年月日
optional birthdate: null | string;
メールアドレス
optional email: null | string;
メールアドレス確認済
optional email_verified: null | boolean;
名字
optional family_name: null | string;
性別
optional gender: null | string;
名前
optional given_name: null | string;
ID
optional id: null | string;
ロケール
optional locale: null | string;
ミドルネーム
optional middle_name: null | string;
名前
optional name: null | string;
ニックネーム
optional nickname: null | string;
電話番号
optional phone_number: null | string;
写真
optional picture: any;
優先ユーザー名
optional preferred_username: null | string;
profile?
optional profile: null | string;
sub?
optional sub: null | string;
updated_at?
optional updated_at: null | string | number | Date;
website?
optional website: null | string;
zoneinfo?
optional zoneinfo: null | string;
Session
ログインユーザーのアクティブなセッション。
Extends
Properties
expires
expires: string;
Inherited from
user?
optional user: User;
Inherited from
User
OAuthプロバイダのprofile
コールバックで返されるオブジェクトの形状。 jwt
およびsession
コールバック、またはデータベースを使用する場合のsession
コールバックの第2パラメータで使用できます。
Extended by
Properties
email?
optional email: null | string;
id?
optional id: string;
image?
optional image: null | string;
name?
optional name: null | string;
customFetch
const customFetch: unique symbol;
このオプションを使用すると、プロバイダがプロバイダのOAuthエンドポイントに直接リクエストを行うために使用するデフォルトのfetch
関数をオーバーライドできます。誤って使用すると、セキュリティ上の問題が発生する可能性があります。
企業プロキシ、カスタムフェッチライブラリ、キャッシュ検出エンドポイントのサポート、テストのためのモックの追加、ロギング、非標準準拠プロバイダのカスタムヘッダー/パラメータの設定などに使用できます。
Example
import { Auth, customFetch } from "@auth/core"
import GitHub from "@auth/core/providers/github"
const dispatcher = new ProxyAgent("my.proxy.server")
function proxy(...args: Parameters<typeof fetch>): ReturnType<typeof fetch> {
return undici(args[0], { ...(args[1] ?? {}), dispatcher })
}
const response = await Auth(request, {
providers: [GitHub({ [customFetch]: proxy })]
})
See
- https://undici.nodejs.org/#/docs/api/ProxyAgent?id=example-basic-proxy-request-with-local-agent-dispatcher
- https://authjs.dokyumento.jp/guides/corporate-proxy
SvelteKitAuth()
SvelteKitAuth(config): {
handle: Handle;
signIn: Action;
signOut: Action;
}
@auth/sveltekit
のメインエントリポイント。
Parameters
パラメータ | 型 |
---|---|
config | SvelteKitAuthConfig | (event ) => PromiseLike <SvelteKitAuthConfig > |
Returns
{
handle: Handle;
signIn: Action;
signOut: Action;
}
handle
handle: Handle;
signIn
signIn: Action;
signOut
signOut: Action;