开发心得

部署

其他

开发环境的准备

本文阐述了基于 Node 大型前端开发环境配搭 AJ-IAM 在开发者本地的准备,一般是 VSCode + Eclipse/IDEA + Nginx 的环境。 假设你的前端程序是 React/VueJs 的大型前端环境,那么本文正好适合你。下面介绍所需的工具环境。

相对于纯 HTML 前端(打包后的 React/Vue 亦算),开发环境的配置是比较复杂的,所以请耐心陪同我在下面的教程中了解如何搭建。、

下载源码运行 IAM

这一步就不详细说了,执行main()函数运行 SpringBoot 程序,端口号默认是 8082。 访问接口http://localhost:8082/iam_api/返回 JSON:

{
    "status": 1,
    "errorCode": null,
    "traceId": "E9395E4765E244CE8080A44137296E4D",
    "message": null,
    "data": "Hello World"
}

该接口仅仅是用于测试的接口,只返回 Hello World。

域名映射 IP

就是修改本地 hosts 文件,将域名映射到 IP。下面以 windows 系统为例子,打开C:\Windows\System32\drivers\etc\hosts文件。 增加一笔域名的映射,例如:

127.0.0.1       local.foo.com

Nginx

server {
    listen       80;
    server_name  local.foo.com;

    location / { # 登录页面
        ssi on;
        alias D:/sp42/code/ajaxjs/aj-iam/aj-iam-admin/;  # 注意路径斜杠
        index index.html index.htm; # 默认首页
        try_files $uri $uri/ /index.html; # 支持单页应用(SPA)路由
        autoindex on;  # 可选,显示目录列表
    }

    location /iam_api/ {# 代理到后端 API
        proxy_pass http://localhost:8082/iam_api/; 
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header auth-tenant-id 8; # 添加租户ID
    }      
}

这样加了第一层的代理,就可以local.foo.com访问 IAM 接口,在 Postman 里面测试下。

Client 配置

IAM 配置好之后,将 IAM 访问地址配置到 Client 端,所谓 Client 就是你的业务系统,整合了 iam-client SDK 的。

在 yaml 文件中配置auth.iam_serviceauth.self_urliam_service是刚才我们配好的 Nginx 代理地址;self_url是 client 就是业务系统本身的地址, 因为当前我们在 nodejs 的开发环境中,须使用代理的地址:http://localhost:3000而不是在 IDEA 运行的那个地址

配置好之后 Client 运行起来,让前端可以访问。

访问 IAM User API

问题的出现

像 IAM 这样的认证中心,管理着用户相关的接口,比如获取用户信息,修改用户信息,修改用户密码等的接口。 认证中心是独立的进程和有自己的域 Domain,业务系统本身没有用户管理功能,而是通过 IAM SDK 与 IAM 整合。 当业务系统需要获取用户信息,修改用户信息,修改用户密码的时候,应该怎么和 IAM 整合比较好, 因为涉及跨域调用,这样的话把 AccessToken 存储在 httponly 的 cookie 则无用,但又不能显式存储 Token 在 localStorage 这类地方(安全性的缘故)。

我想到一个方法,就是在业务系统搞一个类似 Nginx 的转发代理, 专门针对 获取用户信息,修改用户信息,修改用户密码等的业务,转发到 IAM,把本地的认证信息(cookie 传入)提取 token 再转发到 IAM。

实际上这属于BFF(Backend For Frontend)/后端代理的思路。

开发环境

这里以 Vue3 的 Vite 开发环境为例子,其他 React 的大同小异。 首先规定前端访问前缀的/rdd/rdd_api/iam_user都是访问 IAM User API的,那么接着就在 Vite 添加一条路由转发规则:

const init: ProxyTargetList = {
    "/rdd/rdd_api/iam_user": iamProxyOptions as ProxyTargetList,
    [env.VITE_APP_BASE_API]: commonProxyOptions as ProxyTargetList, // 这是业务系统 API
}

注意顺序越靠前的优先级越高,IAM 的在非 IAM 签名前面。再看看 IAM 的代理配置:

  let iamProxyOptions: ProxyOptions = {
    target: env.VITE_APP_IAM_URL, // 'http://local.foo.com/iam_api'
    changeOrigin: true,
    rewrite: (path: string) => {
      return path.replace(/\/rdd\/rdd_api\/iam_user/, '');
    },
  };

开始以为 Cookie 的SameSite = strict限制跨域,IAM API 不能接受,但实际测试发现,Cookie 也可以直接传,不需要转换。

如果 IAM API 不能接受,那么也可以通过 Vite 的configureproxy.on('proxyReq')事件转换 Cookie 为 HTTP Head 给 IAM。

线上环境

这里注意两点,原先 IAM 的 HTTPS 经过 Nginx 转发不行,于是改用非 HTTPS 的;另外 HOST 已强制指定,否则 404。

location /rdd/rdd_api/iam_user/ { # 代理 IAM User
    proxy_pass http://iamtest.ajaxjs.com/iam_api/; # 不要 SSL,证书不行
    proxy_set_header Host iamtest.ajaxjs.com; # 自定义 host
}

开始以为 Cookie 的SameSite = strict限制跨域,IAM API 不能接受,但实际测试发现,Cookie 也可以直接传,不需要转换。

如果 IAM API 不能接受,那么也可以通过 Nginx 转换 Cookie 为 HTTP Head 给 IAM。