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


    视频地址: https://www.bilibili.com/video/BV12d4y1R7bR/


    初始化项目

    Remix 官网:https://remix.run/

    创建命令:

    npx create-remix@latest
    
    • 1

    目前项目源码位于: https://github.com/willin/beta.willin.wang

    配置

    • 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}`
      );
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    注销接口

    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'
        )}`
      );
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    登录回调 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);
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
  • 相关阅读:
    大端 小端?
    【JVM技术专题】网络问题分析和故障排查规划指南「实战篇」
    jupyter notebook中激活python的虚拟环境
    owt-server源码剖析(七)--MCU模式介绍
    VMware中Ubuntu(Linux)无法连接网络解决办法记录
    java 实现串口通讯
    Linux~常用命令的使用
    android 12出现 Targeting S+ (version 31 and above)问题
    整数分组(冬季每日一题 16)
    在列表中按照概率抽样choice()
  • 原文地址:https://blog.csdn.net/jslygwx/article/details/126432947