爱发电 OAuth 文档: https://afdian.net/p/010ff078177211eca44f52540025c377
注意一下这里有两个细节:
代码仓库: https://github.com/willin/remix-auth-afdian
在线演示: https://remix-auth-afdian.willin.wang/
包名: remix-auth-afdian
npm i --save remix-auth-afdian
# or
pnpm i remix-auth-afdian
# or
yarn add remix-auth-afdian
在项目根目录下创建一个 auth.server.ts
代码文件:
import { createCookieSessionStorage, type ActionFunctionArgs } from '@remix-run/cloudflare';
import { Authenticator } from 'remix-auth';
import { AfdianStrategy } from 'remix-auth-afdian/build/index';
export function getAuthenticator({ context, request }: ActionFunctionArgs) {
const url = new URL(request.url);
url.pathname = '/auth/afdian/callback';
const sessionStorage = createCookieSessionStorage({
cookie: {
name: 'sid',
httpOnly: true,
secure: context.env.CF_PAGES === 'production',
sameSite: 'lax',
path: '/',
secrets: ['s3cr3t']
}
});
const authenticator = new Authenticator(sessionStorage, {
throwOnError: true
});
const afdianStrategy = new AfdianStrategy(
{
clientID: context.env.AFDIAN_CLIENT_ID,
clientSecret: context.env.AFDIAN_CLIENT_SECRET,
callbackURL: url.toString()
},
async ({ accessToken, extraParams, profile }) => {
return profile;
}
);
authenticator.use(afdianStrategy);
return authenticator;
}
替换其中的配置,如:
@remix-run/cloudflare
根据需要,切换 Remix 运行环境创建 auth.afdian.tsx
文件:
import { type ActionFunctionArgs, redirect } from "@remix-run/cloudflare";
import { getAuthenticator } from "~/auth.server";
export async function loader() {
return redirect("/");
}
export async function action(args: ActionFunctionArgs) {
const authenticator = getAuthenticator(args);
return await authenticator.authenticate("afdian", args.request, {
successRedirect: "/dashboard",
});
}
注意:该文件命名采用的是 remix v2 规则,v1 的话用目录分隔。
创建 auth.afdian.callback.tsx
文件:
import { getAuthenticator } from '~/auth.server';
export async function loader(args) {
const authenticator = getAuthenticator(args);
return authenticator.authenticate('afdian', args.request, {
successRedirect: '/dashboard',
failureRedirect: '/'
});
}
这样已经大功告成了。
比如这里叫 dashboard.tsx
页面:
import { json, redirect } from '@remix-run/cloudflare';
import { Form, useLoaderData } from '@remix-run/react';
import { getAuthenticator } from '~/auth.server';
export async function loader(args) {
const authenticator = getAuthenticator(args);
const user = await authenticator.isAuthenticated(args.request);
if (!user) {
throw redirect('/');
}
return json(user);
}
export default function Page() {
const data = useLoaderData<typeof loader>();
return (
<div>
<h1>已登录 Logged in</h1>
<p>
<Form action='/api/logout' method='POST'>
<button>Logout</button>
</Form>
</p>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
import { type LoaderFunction, type ActionFunction, redirect } from '@remix-run/cloudflare';
import { getAuthenticator } from '~/auth.server';
export const loader: LoaderFunction = () => {
return redirect('/');
};
export const action: ActionFunction = async (args) => {
const { request } = args;
const authenticator = getAuthenticator(args);
const referer = request.headers.get('referer');
const returnPath = referer ? new URL(referer).pathname : '/';
return await authenticator.logout(request, {
redirectTo: returnPath
});
};
这个可以根据需要添加。
如果您对爱发电感兴趣,想要让其支持更多的框架。可以联系我进行定制开发。
打赏地址:https://afdian.net/a/willin
感谢您的观看~