搭建个人知识付费应用系统-(1)框架初始化、用户身份集成

视频地址: https://www.bilibili.com/vide...
初始化项目 Remix 官网:https://remix.run/
创建命令:

npx create-remix@latest

目前项目源码位于: https://github.com/willin/bet...
配置
  • eslint
  • prettier
  • editorconfig
可选项:
  • lint-staged
  • husky
安装依赖
  • tailwindcss
  • daisyui
  • @tailwindcss/typography
  • postcss
  • pm2
创建 Authing 用户池及应用
【搭建个人知识付费应用系统-(1)框架初始化、用户身份集成】创建登录、注销接口
登录接口
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}` ); };

注销接口
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' )}` ); };

登录回调 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 = https://www.it610.com/article/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); };

    推荐阅读