Video address: https://www.bilibili.com/video/BV12d4y1R7bR/
Initialize the project
Remix official website: https://remix.run/
Create command:
npx create-remix@latest
The current project source code is located at: https://github.com/willin/beta.willin.wang
configure
- eslint
- prettier
- editorconfig
Optional:
- lint-staged
- husky
Install dependencies
- tailwindcss
- daisyui
- @tailwindcss/typography
- postcss
- pm2
Create Authing user pool and application
Create login and logout interfaces
login interface
import { redirect } from '@remix-run/node';
export const loader = async () => {
return redirect(
`${process.env.AUTHING_SSO_URL}/login?app_id=${process.env.AUTHING_APP_ID}`
);
};
logout interface
import { redirect } from '@remix-run/node';
export const loader = async () => {
return redirect(
`${process.env.AUTHING_SSO_URL}/logout?redirectUri=${encodeURIComponent(
process.env.HOMEPAGE || 'https://willin.wang'
)}`
);
};
login callback callback
import { json, redirect } from '@remix-run/node';
export type OidcResponse = {
error?: string;
error_description?: string;
access_token: string;
expires_in: number;
id_token: string;
scope: string;
token_type: string;
};
export const loader = async ({ request }) => {
const url = new URL(request.url);
const code = url.searchParams.get('code');
if (code === null) {
return redirect('/login');
}
const body = {
client_id: process.env.AUTHING_APP_ID,
client_secret: process.env.AUTHING_APP_SECRET,
grant_type: 'authorization_code',
code
};
const formBody = [];
// eslint-disable-next-line
for (const property in body) {
const encodedKey = encodeURIComponent(property);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const encodedValue = encodeURIComponent(body[property]);
formBody.push(`${encodedKey}=${encodedValue}`);
}
const res = await fetch(`${process.env.AUTHING_APP_DOMAIN}/oidc/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
body: formBody.join('&')
});
const oidcToken = (await res.json()) as OidcResponse;
if (oidcToken.error) {
console.error(oidcToken);
return redirect('/login');
}
// 以上获取 oidc token 为核心部分
// 下面根据业务需要去操作其他
const resInfo = await fetch(
`${process.env.AUTHING_APP_DOMAIN}/oidc/me?access_token=${oidcToken.access_token}`
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const user = await resInfo.json();
return json(user);
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。