视频地址: 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 用户池及利用

创立登录、登记接口

登录接口

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 = 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);};