├── changelog
└── README.md
├── deployment
├── jar-runapp.md
├── docker-compose-runapp.md
├── micrometer.md
├── production-environment.md
├── docker-runapp.md
└── deployment-core.md
├── share-file
├── playbook
│ ├── test-playbook.yml
│ ├── 4-node-playbook.yml
│ ├── 2-jdk8-playbook.yml
│ ├── 5-mysql-playbook.yml
│ ├── 6-redis-playbook.yml
│ ├── 1-install-basic-playbook.yml
│ ├── 3-maven-playbook.yml
│ └── 7-nginx-playbook.yml
├── shell
│ └── runapp.sh
└── postman
│ └── tkey-sso-server-api_collection_2.1_format.json
├── client
├── dev-spring-security-client.md
└── dev-rest-client.md
├── server
├── oauth-grant-type
│ ├── README.md
│ ├── token.md
│ ├── client_credentials.md
│ ├── password.md
│ ├── code.md
│ └── common.md
├── remote-debug.md
└── dev.md
├── roadmap
└── README.md
├── management
├── dev-backend.md
└── dev-frontend.md
├── .editorconfig
├── SUMMARY.md
├── .gitignore
├── other
├── project-structure.md
└── tkey-baisc.md
├── test
└── performance.md
├── .gitattributes
├── faq
└── README.md
└── README.md
/changelog/README.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.0.0(2019-08-27)
4 |
5 | - 撒花上线
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/deployment/jar-runapp.md:
--------------------------------------------------------------------------------
1 |
2 | ## JAR 方式
3 |
4 | - [点击我查看整个过程 Gif 演示](http://img.gitnavi.com/tkey/tkey-runapp-jar.gif)
5 | - 把 jar 文件和 runapp.sh 上传到 /data/jar/tkey-sso-server 目录下
6 | - 给两个文件增加执行权限:`chmod +x runapp.sh tkey-sso-server-1.0.0.jar`
7 | - 运行命令:`sh runapp.sh start`
8 | - 如果需要调整目录位置、端口、启动参数(Redis 连接参数),可以自行修改 runapp.sh 文件,该脚本写得很简单,一般都可以看懂
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/share-file/playbook/test-playbook.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | remote_user: root
3 | tasks:
4 | - name : ansible-test
5 | shell : sleep 30
6 | async : 1000
7 | poll : 0
8 | register: kevin_result
9 |
10 | - name: 'check ansible-test task polling results '
11 | async_status: jid={{ kevin_result.ansible_job_id }}
12 | register: job_result
13 | until: job_result.finished
14 | retries: 200
15 |
--------------------------------------------------------------------------------
/client/dev-spring-security-client.md:
--------------------------------------------------------------------------------
1 | ## TKey Client 开发环境
2 |
3 | - [参考 TKey SSO Server 环境](https://github.com/cdk8s/tkey-docs/blob/master/server/dev.md)
4 |
5 | ## TKey Client 项目核心组件版本
6 |
7 | - [参考 TKey SSO Server 环境](https://github.com/cdk8s/tkey-docs/blob/master/server/dev.md)
8 |
9 |
10 | ## Spring Boot 1.5.x 和 2.1.x 的区别
11 |
12 | - Spring Boot 1.5.x 搭配 Spring Security 4 一起使用
13 | - Spring Boot 2.1.x 搭配 Spring Security 5 一起使用
14 | - Spring Security 4 和 5 变化比较大,所以分开了两个项目进行演示
15 | - 虽然 TKey SSO 支持 Spring Security OAuth2 客户端,但是因为 Spring Security 封装过多,较庞大,所以还是推荐你使用 TKey 自己的 Client,可以控制的细节内容会多得多
16 |
--------------------------------------------------------------------------------
/deployment/docker-compose-runapp.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Docker Compose 启动 TKey SSO Server + Redis
4 |
5 | - git clone 项目
6 | - 保持在项目根目录,输入:`mvn clean install -DskipTests`
7 | - 保持在项目根目录,输入:`docker-compose -f ./docker-compose-quickstart.yml up --build -d`
8 |
9 | ## 测试
10 |
11 | - cURL 测试结果:
12 |
13 | ```
14 | curl -X POST \
15 | http://sso.cdk8s.com:9091/sso/oauth/token \
16 | -H 'Content-Type: application/x-www-form-urlencoded' \
17 | -H 'cache-control: no-cache' \
18 | -d 'grant_type=password&client_id=test_client_id_1&client_secret=test_client_secret_1&username=admin&password=123456'
19 | ```
20 |
--------------------------------------------------------------------------------
/deployment/micrometer.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 相应组件部署
4 |
5 | - [部署说明](https://github.com/cdk8s/tkey-docs/blob/master/deployment/deployment-core.md)
6 |
7 | ## 引入 Prometheus
8 |
9 | ```
10 |
11 | io.micrometer
12 | micrometer-registry-prometheus
13 |
14 | ```
15 |
16 |
17 | 访问:
18 |
19 | 可以看到 prometheus 暴露出来的埋点信息
20 |
21 |
22 | ## Micrometer Tag
23 |
24 | ```
25 | $instance - Instance Name
26 | $application - Spring Boot Application Name
27 | $hikaricp - HikariCP Connection Pool Name
28 | ```
29 |
30 |
--------------------------------------------------------------------------------
/server/oauth-grant-type/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## 授权码模式
3 |
4 | - [点击我查看](https://github.com/cdk8s/tkey-docs/blob/master/server/oauth-grant-type/code.md)
5 |
6 | ## 密码模式
7 |
8 | - [点击我查看](https://github.com/cdk8s/tkey-docs/blob/master/server/oauth-grant-type/password.md)
9 |
10 | ## 简化模式
11 |
12 | - [点击我查看](https://github.com/cdk8s/tkey-docs/blob/master/server/oauth-grant-type/token.md)
13 |
14 | ## 客户端模式
15 |
16 | - [点击我查看](https://github.com/cdk8s/tkey-docs/blob/master/server/oauth-grant-type/client_credentials.md)
17 |
18 | ## 通用接口
19 |
20 | - [点击我查看](https://github.com/cdk8s/tkey-docs/blob/master/server/oauth-grant-type/common.md)
21 |
--------------------------------------------------------------------------------
/server/remote-debug.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 配置 IntelliJ IDEA 远程 Debug
4 |
5 |
6 | 
7 |
8 |
9 | - **复制这个 VM 配置**
10 |
11 | ```
12 | -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
13 | ```
14 |
15 |
16 | ## 调整应用启动参数
17 |
18 | - 在 应用的原有 JAVA_OPTS 参数基础上补加,效果如下:
19 |
20 | ```
21 | JAVA_OPTS="-Xms512m -Xmx2048m -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
22 | ```
23 |
24 |
25 | ## 启动本地项目
26 |
27 | 
28 |
29 | - 然后在项目代码中打断点,跟平时本地 debug 一样
30 |
31 |
32 | 
33 |
--------------------------------------------------------------------------------
/roadmap/README.md:
--------------------------------------------------------------------------------
1 | # Roadmap
2 |
3 | ## 1.0.1
4 |
5 | - 登录日志记录到 MySQL
6 |
7 | ## 1.0.2
8 |
9 | - 各类配置开关
10 | - 登录错误次数展示验证码
11 |
12 | ## 1.0.3
13 |
14 | - 企业微信扫码登录
15 |
16 | ## 1.0.4
17 |
18 | - 钉钉扫码登录
19 |
20 | ## 1.1.0
21 |
22 | - 普通微信扫码登录
23 |
24 | ## 1.1.1
25 |
26 | - QQ 登录
27 |
28 | ## 1.1.2
29 |
30 | - 微博登录
31 |
32 | ## 1.1.3
33 |
34 | - 小程序登录
35 |
36 | ## 1.1.4
37 |
38 | - 公众号登陆
39 |
40 | ## 1.1.5
41 |
42 | - 基于 K8S 整套方案发布
43 |
44 | ## 2.0.0
45 |
46 | - Github 登录
47 | - Google 登录
48 | - Facebook 登录
49 | - Twitter 登录
50 |
51 | ## 3.0.0
52 |
53 | - 自己 APP 的扫码登录
54 | - geetest 验证码
55 | - vaptcha 验证码
56 | - 多语言
57 | - 多因素认证
58 | - 人脸识别登录(旷视,腾讯AI)
59 | - LDAP
60 |
--------------------------------------------------------------------------------
/management/dev-backend.md:
--------------------------------------------------------------------------------
1 |
2 | ## TKey Client Management 开发环境
3 |
4 | - [参考 TKey SSO Server 环境](https://github.com/cdk8s/tkey-docs/blob/master/server/dev.md)
5 |
6 | ## TKey Client Management 项目核心组件版本
7 |
8 | - [参考 TKey SSO Server 环境](https://github.com/cdk8s/tkey-docs/blob/master/server/dev.md)
9 |
10 |
11 | ## TKey Client Management Token 有效期设置
12 |
13 |
14 | 在没有 API 网关的情况下,各业务系统的 Token 是自己维护的。
15 |
16 | Client Management 的 Token 有效时长参数是:`token-max-time-to-live-in-seconds: 86400`,也就是 24 小时
17 |
18 | 如果你设置为 30 秒,其实也没事。用户体验上会出现:用户登录操作 30 秒之后,浏览器又重定向到 TKey SSO 重新生成了新 Token,整个过程依旧还是不需要用户重新输入账号密码。因为 TGC 的有效期很长。
19 |
20 |
21 | ## H2 数据库
22 |
23 | 为了方便开发,默认 `application-dev.yml` 是 H2 数据库。
24 |
25 | 为了生产 MySQL 的需要,也带有 `application-devmysql.yml`,大家可以自行切换
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/share-file/playbook/4-node-playbook.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | remote_user: root
3 | tasks:
4 | - name: remove the nodejs
5 | yum:
6 | name: nodejs
7 | state: absent
8 |
9 | - name: remove the npm
10 | yum:
11 | name: npm
12 | state: absent
13 |
14 | - name: curl node
15 | shell: "curl --silent --location https://rpm.nodesource.com/setup_12.x | sudo bash -"
16 |
17 | - name: install node
18 | command: "{{ item }}"
19 | with_items:
20 | - yum -y install nodejs
21 |
22 | - name: curl yarn
23 | shell: "curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo"
24 |
25 | - name: install yarn
26 | command: "{{ item }}"
27 | with_items:
28 | - yum -y install yarn
29 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 4
7 | charset = utf-8
8 | end_of_line = lf
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 | max_line_length = 300
12 |
13 | [*.{groovy,java,kt,kts}]
14 | indent_style = tab
15 | continuation_indent_size = 8
16 |
17 | [*.{xml,xsd}]
18 | indent_style = tab
19 |
20 | [Makefile]
21 | indent_style = tab
22 |
23 | [*.py]
24 | indent_size = 4
25 |
26 | [*.js]
27 | indent_size = 4
28 |
29 | [*.ts]
30 | indent_size = 4
31 |
32 | [*.html]
33 | indent_size = 4
34 |
35 | [*.{less,css}]
36 | indent_size = 2
37 |
38 | [*.json]
39 | indent_size = 2
40 |
41 | [*.{tsx,jsx}]
42 | indent_size = 2
43 |
44 | [*.yml]
45 | indent_size = 2
46 |
47 | [*.sql]
48 | indent_size = 2
49 |
50 | [*.md]
51 | insert_final_newline = false
52 | trim_trailing_whitespace = false
53 |
--------------------------------------------------------------------------------
/client/dev-rest-client.md:
--------------------------------------------------------------------------------
1 | ## TKey Client 开发环境
2 |
3 | - [参考 TKey SSO Server 环境](https://github.com/cdk8s/tkey-docs/blob/master/server/dev.md)
4 |
5 | ## TKey Client 项目核心组件版本
6 |
7 | - [参考 TKey SSO Server 环境](https://github.com/cdk8s/tkey-docs/blob/master/server/dev.md)
8 |
9 |
10 | ## Maven 中央库已发布
11 |
12 | - 中央库地址:
13 | - Maven
14 |
15 | ```
16 | 1.0.0
17 |
18 |
19 |
20 | com.cdk8s.tkey
21 | tkey-sso-client-starter-rest
22 | ${tkey-sso-client-starter-rest.version}
23 |
24 | ```
25 |
26 | - Gradle Groovy DSL:
27 |
28 | ```
29 | implementation 'com.cdk8s.tkey:tkey-sso-client-starter-rest:1.0.0'
30 | ```
31 |
32 | - Gradle Kotlin DSL
33 |
34 | ```
35 | compile("com.cdk8s.tkey:tkey-sso-client-starter-rest:1.0.0")
36 | ```
--------------------------------------------------------------------------------
/deployment/production-environment.md:
--------------------------------------------------------------------------------
1 |
2 | # 生产提醒
3 |
4 | - 请不要轻视安全问题,这是一个永远永远都要放心上的问题
5 | - 请结合该篇一起阅读:
6 | - 故意设计点(常见问题):[Github](https://github.com/cdk8s/tkey-docs/blob/master/faq/README.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/faq/README.md)
7 |
8 | ## 必备要求
9 |
10 | 1. 全网 HTTPS,全网 HTTPS,全网 HTTPS
11 | 2. 不要明文存储用户密码,不要明文,不要明文(前端 MD5 后再传输)
12 | 4. Cookie 的 httpOnly 和 secure 都为 true
13 |
14 |
15 | ## 可以额外改造的
16 |
17 | 3. Token 绑定 IP 和 User-Agent
18 | 5. 客户端必传 state 防止 CSRF
19 | 5. 增加多因素认证
20 | 6. 增加异地登入审查
21 | 6. 分析异常登入记录
22 |
23 | ## 关于 Client 信息管理
24 |
25 | - 在 TKey Server 中有一个类:`ApplicationTestDataInitRunner.java` 会在本地开发环境、测试环境生成一个测试专用的 Client
26 | - 如果你已经准备上对外测试、生产记得梳理下 Client 的管理。默认是应该在 TKey Management 项目中进行管理 Client,而 TKey Server 只是读取 Client
27 | - TKey Management 中也有一个类:`ApplicationTestDataInitRunner.java` 会在本地开发环境、测试环境启动的时候读取 H2 数据库,初始化 Client 到 Redis 中
28 | - 以上两个人类都没有强加在 Prod 环境,担心开发者无意识地操作,造成生产事故,所以大家如果需要这个初始化,需要自己评估,并且开启在 Prod 环境下
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/server/oauth-grant-type/token.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Postman 接口集分享
4 |
5 | - 链接地址:
6 | - [Postman 导入 TKey 接口集方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-import-link.gif)
7 | - [Postman 接口转 cURL 方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-to-curl.gif)
8 |
9 | ## 简化模式
10 |
11 | - **GET 请求**
12 | - 请求地址:
13 | - 参数:
14 |
15 | ```
16 | response_type: token
17 | client_id: test_client_id_1
18 | redirect_uri: http://www.gitnavi.com
19 | ```
20 |
21 | ### 浏览器访问
22 |
23 | -
24 |
25 | ### 请求参数合法,系统返回
26 |
27 | - 状态码 302
28 | - Location
29 |
30 | ```
31 | http://www.gitnavi.com#access_token=AT-TxshSaBDm0RMxFEw1osvnFE7PIJmBvWU-103&token_type=Bearer&expires_in=57600&refresh_token=RT-WHD9vlVxiB4Q2XB0OnCrXHeLnptyIbPv-104
32 | ```
33 |
34 |
35 | ### 请求参数不合法,系统返回
36 |
37 | - 停留在登录页面或跳转到 error 页面
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/share-file/playbook/2-jdk8-playbook.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | remote_user: root
3 | vars:
4 | java_install_folder: /usr/local
5 | file_name: jdk-8u261-linux-x64.tar.gz
6 | tasks:
7 | - name: copy jdk
8 | copy:
9 | src=/opt/{{ file_name }}
10 | dest={{ java_install_folder }}
11 |
12 | - name: tar jdk
13 | shell:
14 | chdir={{ java_install_folder }}
15 | tar zxf {{ file_name }}
16 |
17 | - name: set JAVA_HOME
18 | blockinfile:
19 | path: /root/.zshrc
20 | marker: "#{mark} JDK ENV"
21 | block: |
22 | JAVA_HOME={{ java_install_folder }}/jdk1.8.0_261
23 | JRE_HOME=$JAVA_HOME/jre
24 | PATH=$PATH:$JAVA_HOME/bin
25 | CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
26 | export JAVA_HOME
27 | export JRE_HOME
28 | export PATH
29 | export CLASSPATH
30 |
31 | - name: source zshrc
32 | shell: source /root/.zshrc
33 |
34 | - name: remove tar.gz file
35 | file:
36 | state: absent
37 | path: "{{ java_install_folder }}/{{ file_name }}"
38 |
--------------------------------------------------------------------------------
/SUMMARY.md:
--------------------------------------------------------------------------------
1 | * 认识阶段 (必读)
2 | * [单点登录系统认知与基础介绍](other/tkey-baisc.md)
3 | * [故意设计点(常见问题)](faq/README.md)
4 | * [项目结构与端口占用](other/project-structure.md)
5 | * [OAuth2.0 四种模式](server/oauth-grant-type/README.md)
6 | * [JAR 方式部署](deployment/jar-runapp.md)
7 | * [Docker 方式部署](deployment/docker-runapp.md)
8 | * [Docker Compose 方式部署](deployment/docker-compose-runapp.md)
9 | * TKey Server 开发阶段
10 | * [开发改造引导](server/dev.md)
11 | * TKey Management 开发阶段(也是前后端分离的最佳实践示例)
12 | * [后端开发改造引导](management/dev-backend.md)
13 | * [前端开发改造引导](management/dev-frontend.md)
14 | * TKey Client Java 开发阶段
15 | * [自己封装的 REST Client](client/dev-rest-client.md)
16 | * [Spring Security 支持](client/dev-spring-security-client.md)
17 | * 测试阶段
18 | * 单元测试
19 | * [压力测试](test/performance.md)
20 | * 部署阶段
21 | * [生产注意事项](deployment/production-environment.md)
22 | * [部署环境搭建](deployment/deployment-core.md)
23 | * 监控阶段
24 | * [Spring Boot Micrometer](deployment/micrometer.md)
25 | * 其他工具全在 `部署环境搭建`,请自行查看
26 | * 线上问题诊断
27 | * [Actuator 在线修改 log 输出级别(Gif 动图)](http://img.gitnavi.com/tkey/actuator-update-log-level.gif)
28 | * [Arthas 诊断 Docker 应用](https://alibaba.github.io/arthas/docker.html#dockerjava)
29 | * [夜间开放端口,挑选流量远程 Debug](server/remote-debug.md)
--------------------------------------------------------------------------------
/deployment/docker-runapp.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 手工构建镜像
4 |
5 | - git clone 项目
6 | - 保持在项目根目录,输入:`mvn clean install -DskipTests`
7 | - 保持在项目根目录,输入:`docker build . -t cdk8s/tkey-sso-server`
8 | - 查看镜像大小:`docker images`
9 |
10 | ```
11 | cdk8s/tkey-sso-server latest e0eefff8590b 4 seconds ago 205MB
12 | ```
13 |
14 |
15 | ## 启动 TKey SSO Server(使用外部 Redis)
16 |
17 | - 启动容器:(挂载路径大家自行修改)
18 |
19 | ```
20 | docker run -d \
21 | -p 9091:9091 \
22 | --add-host redis.cdk8s.com:192.168.0.107 \
23 | --name=tkey-sso-server --hostname=tkey-sso-server \
24 | --restart=unless-stopped \
25 | -v /Users/youmeek/docker_data/logs/:/logs/ \
26 | -v /Users/youmeek/docker_data/headDump/:/data/headDump/ \
27 | -e SPRING_PROFILES_ACTIVE=test \
28 | -e SPRING_REDIS_DATABASE=0 \
29 | -e SPRING_REDIS_PORT=6379 \
30 | -e SPRING_REDIS_HOST=redis.cdk8s.com \
31 | -e SPRING_REDIS_PASSWORD=123456 \
32 | -e TKEY_NODE_NUMBER=10 \
33 | -e JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MetaspaceSize=124m -XX:MaxMetaspaceSize=224m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/headDump" \
34 | cdk8s/tkey-sso-server:latest
35 | ```
36 |
37 | ## 测试
38 |
39 | - cURL 测试结果:
40 |
41 | ```
42 | curl -X POST \
43 | http://sso.cdk8s.com:9091/sso/oauth/token \
44 | -H 'Content-Type: application/x-www-form-urlencoded' \
45 | -H 'cache-control: no-cache' \
46 | -d 'grant_type=password&client_id=test_client_id_1&client_secret=test_client_secret_1&username=admin&password=123456'
47 | ```
--------------------------------------------------------------------------------
/server/oauth-grant-type/client_credentials.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Postman 接口集分享
4 |
5 | - 链接地址:
6 | - [Postman 导入 TKey 接口集方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-import-link.gif)
7 | - [Postman 接口转 cURL 方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-to-curl.gif)
8 |
9 | ## 客户端模式
10 |
11 | - **GET 请求**
12 | - 请求地址:
13 | - 参数:
14 |
15 | ```
16 | grant_type: client_credentials
17 | client_id: test_client_id_1
18 | client_secret: test_client_secret_1
19 | ```
20 |
21 | - 也支持请求头验证 client:`Authorization: Basic dGVzdF9jbGllbnRfaWRfMTp0ZXN0X2NsaWVudF9zZWNyZXRfMQ==`
22 |
23 |
24 | ### cURL
25 |
26 | ```
27 | curl -X GET \
28 | 'http://sso.cdk8s.com:9091/sso/oauth/token?grant_type=client_credentials&client_id=test_client_id_1&client_secret=test_client_secret_1' \
29 | -H 'cache-control: no-cache'
30 | ```
31 |
32 |
33 | ### 请求参数合法,系统返回
34 |
35 | - 状态码 200
36 | - JSON 数据
37 |
38 | ```
39 | {
40 | "access_token": "AT-102-dJTLEsFLR2PbxU1l8GPx3CUS9O3Lhzdn",
41 | "token_type": "Bearer",
42 | "expires_in": 57600,
43 | "refresh_token": "RT-mTeOPJHDbcDeeUhRM0V52giRgiisu6ar-102"
44 | }
45 | ```
46 |
47 |
48 | ### 请求参数不合法,系统返回
49 |
50 | - 状态码 400
51 | - JSON 数据
52 |
53 | ```
54 | {
55 | "error": "invalid request",
56 | "error_description": "请求类型不匹配",
57 | "error_uri_msg": "See the full API docs at https://github.com/cdk8s"
58 | }
59 | ```
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/management/dev-frontend.md:
--------------------------------------------------------------------------------
1 |
2 | ## TKey Client Management 开发环境
3 |
4 | - [参考 TKey SSO Server 环境](https://github.com/cdk8s/tkey-docs/blob/master/server/dev.md)
5 |
6 | ## TKey Client Management 项目核心组件版本
7 |
8 | - 依赖包完整列表 package.json:[Github](https://github.com/cdk8s/tkey-management-frontend/blob/master/package.json)、[Gitee](https://gitee.com/cdk8s/tkey-management-frontend/blob/master/package.json)
9 |
10 | -------------------------------------------------------------------
11 |
12 | ## 前后端分离的场景特别说明
13 |
14 | ### 相同二级域名
15 |
16 | - 前端:f.cdk8s.com
17 | - 后端:b.cdk8s.com
18 | - 这种场景下,后端可以通过写入 `.cdk8s.com` Cookie 的方式来存储 Token,前端也可以拿到 Token
19 | - 但是,在前后端分离情况下我更建议采用下面 `不同二级域名` 的解决办法
20 |
21 |
22 | ### 不同二级域名
23 |
24 | - 前端:f.ffffff.com
25 | - 后端:b.bbbbbb.com
26 | - 这种场景下,Cookie 方式不可用
27 | - 只能把 code 的回调地址写成前端系统,前端拿到 code 之后转发给后端,后端把 code 换取到 token 再 response 给前端,前端可以选择存储到 localstorage 中
28 | - 这种方式麻烦的地方在于:本地环境、开发环境、测试环境、生产环境的回调配置
29 |
30 | -------------------------------------------------------------------
31 |
32 | ## 常量参数
33 |
34 | - **在该文件中配置了不同环境的各种需要配置的请求地址**
35 | - globalConstant.ts
36 |
37 | ## 本地环境使用
38 |
39 | - `.umirc.ts`
40 |
41 |
42 | ```
43 | yarn install
44 |
45 | yarn start
46 |
47 | yarn build
48 | ```
49 |
50 |
51 | ## 测试环境使用
52 |
53 | - `.umirc.test.ts`
54 |
55 | ```
56 | yarn install
57 |
58 | yarn start:test
59 |
60 | yarn build:test
61 | ```
62 |
63 |
64 | ## 生产环境使用
65 |
66 | - `.umirc.prod.ts`
67 |
68 | ```
69 | yarn install
70 |
71 | yarn start:prod
72 |
73 | yarn build:prod
74 | ```
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/server/oauth-grant-type/password.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Postman 接口集分享
4 |
5 | - 链接地址:
6 | - [Postman 导入 TKey 接口集方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-import-link.gif)
7 | - [Postman 接口转 cURL 方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-to-curl.gif)
8 |
9 | ## 密码模式
10 |
11 | - **POST 请求**
12 | - 请求地址:
13 | - 参数:
14 |
15 | ```
16 | grant_type: password
17 | client_id: test_client_id_1
18 | client_secret: test_client_secret_1
19 | username: admin
20 | password: 123456
21 |
22 | ```
23 |
24 | - 也支持请求头验证 client:`Authorization: Basic dGVzdF9jbGllbnRfaWRfMTp0ZXN0X2NsaWVudF9zZWNyZXRfMQ==`
25 |
26 | ### cURL
27 |
28 |
29 | ```
30 | curl -X POST \
31 | http://sso.cdk8s.com:9091/sso/oauth/token \
32 | -H 'Content-Type: application/x-www-form-urlencoded' \
33 | -H 'cache-control: no-cache' \
34 | -d 'grant_type=password&client_id=test_client_id_1&client_secret=test_client_secret_1&username=admin&password=123456'
35 | ```
36 |
37 | ### 请求参数合法,系统返回
38 |
39 | - 状态码 200
40 | - JSON 数据
41 |
42 | ```
43 | {
44 | "access_token": "AT-MISqrbWUxFWc1xU4e8JK2OcMgJYusF22-101",
45 | "token_type": "Bearer",
46 | "expires_in": 57600,
47 | "refresh_token": "RT-7UPY41g9j5K8rKBZse4qo4iP6sAbU2Df-102"
48 | }
49 | ```
50 |
51 |
52 | ### 请求参数不合法,系统返回
53 |
54 | - 状态码 400
55 | - JSON 数据
56 |
57 | ```
58 | {
59 | "error": "invalid request",
60 | "error_description": "请求类型不匹配",
61 | "error_uri_msg": "See the full API docs at https://github.com/cdk8s"
62 | }
63 | ```
64 |
65 | ### 用户名密码有问题,系统返回
66 |
67 | - 状态码 400
68 | - JSON 数据
69 |
70 | ```
71 | {
72 | "error": "invalid request",
73 | "error_description": "用户名或密码错误",
74 | "error_uri_msg": "See the full API docs at https://github.com/cdk8s"
75 | }
76 | ```
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out/
2 | target/
3 | node_modules/
4 | classes/
5 | .deploy*/
6 | .gradle
7 | *.log.*
8 | *.log
9 |
10 | # ======================================================
11 |
12 | ### STS ###
13 | .apt_generated
14 | .classpath
15 | .factorypath
16 | .project
17 | .settings
18 | .springBeans
19 |
20 | ### IntelliJ IDEA ###
21 | .idea
22 | *.iws
23 | *.iml
24 | *.ipr
25 |
26 | ### NetBeans ###
27 | nbproject/private/
28 | build/
29 | nbbuild/
30 | dist/
31 | nbdist/
32 | .nb-gradle/
33 |
34 | # ======================================================
35 |
36 | # Windows image file caches
37 | Thumbs.db
38 | ehthumbs.db
39 |
40 | # Folder config file
41 | Desktop.ini
42 |
43 | # Recycle Bin used on file shares
44 | $RECYCLE.BIN/
45 |
46 | # Windows Installer files
47 | *.cab
48 | *.msi
49 | *.msm
50 | *.msp
51 |
52 | # Windows shortcuts
53 | *.lnk
54 |
55 | # ======================================================
56 |
57 | # OSX
58 | .DS_Store
59 | .AppleDouble
60 | .LSOverride
61 |
62 | # Thumbnails
63 | ._*
64 |
65 | # Files that might appear in the root of a volume
66 | .DocumentRevisions-V100
67 | .fseventsd
68 | .Spotlight-V100
69 | .TemporaryItems
70 | .Trashes
71 | .VolumeIcon.icns
72 |
73 | # Directories potentially created on remote AFP share
74 | .AppleDB
75 | .AppleDesktop
76 | Network Trash Folder
77 | Temporary Items
78 | .apdisk
79 |
80 | # ======================================================
81 |
82 | npm-debug.log*
83 | yarn-error.log
84 | .idea/
85 | .ipr
86 | .iws
87 | *~
88 | ~*
89 | *.diff
90 | *.patch
91 | *.bak
92 | .*proj
93 | .svn/
94 | *.swp
95 | *.swo
96 | *.json.gzip
97 | .buildpath
98 | nohup.out
99 | dist
100 | *.tmp
101 |
102 | # ======================================================
103 |
104 | .DS_STORE
105 | *.pyc
106 | remote-repo/
107 | coverage/
108 | .module-cache
109 | *.log*
110 | chrome-user-data
111 | *.sublime-project
112 | *.sublime-workspace
113 | .vscode
114 |
115 |
--------------------------------------------------------------------------------
/other/project-structure.md:
--------------------------------------------------------------------------------
1 |
2 | # 项目结构与占用端口
3 |
4 | ## TKey Docs
5 |
6 | - 文档集中维护
7 | - Github:
8 | - Gitee:
9 |
10 | ## TKey SSO Server
11 |
12 | - TKey 单点登录核心系统
13 | - Github:
14 | - Gitee:
15 | - 占用端口
16 | - 9091
17 | - 19091
18 |
19 | ## TKey SSO Client Management
20 |
21 | - TKey Client 管理系统(后端)
22 | - Github:
23 | - Gitee:
24 | - 占用端口
25 | - 9095
26 | - 19095
27 |
28 | ## TKey SSO Client Management Frontend(React)
29 |
30 | - TKey Client 管理系统(前端)
31 | - Github:
32 | - Gitee:
33 | - 占用端口
34 | - 8000
35 |
36 | ## TKey Issues
37 |
38 | - 统一的 issues 提问入口
39 | - Github:
40 | - Gitee:
41 |
42 | ## TKey Test
43 |
44 | - 压力测试脚本
45 | - Github:
46 | - Gitee:
47 |
48 | ## TKey SSO Client Java
49 |
50 | - 我们自己封装的 Java 客户端以及 demo
51 | - Github:
52 | - Gitee:
53 | - 占用端口
54 | - 9094
55 |
56 | ## TKey SSO Client Spring Security
57 |
58 | - 基于 Spring Security OAuth 做客户端
59 | - Github:
60 | - Gitee:
61 | - Spring Boot 2.1.x
62 | - 占用端口
63 | - 9092
64 |
65 | - Spring Boot 1.5.x
66 | - 占用端口
67 | - 9093
68 |
69 |
70 | ## TKey SSO Client Management Frontend(Vue)
71 |
72 | ## TKey SSO Client Management Frontend(Angular)
73 |
74 | ## TKey SSO Client Python
75 |
76 | ## TKey SSO Client Go
77 |
78 | ## TKey SSO Client PHP
79 |
80 | ## TKey SSO Client C Sharp
81 |
82 | ## TKey SSO Client Node
83 |
84 | ## TKey SSO Client Ruby
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/test/performance.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # TKey SSO Server 压力测试
4 |
5 | ## Gatling 方式压力测试
6 |
7 | - 不带参数运行命令:
8 |
9 | ```
10 | mvn gatling:test -Dgatling.simulationClass=test.load.oauth.TkeyPasswordGrantType
11 | ```
12 |
13 |
14 | - 带参数运行命令:
15 |
16 | ```
17 | mvn gatling:test -Dgatling.simulationClass=test.load.oauth.TkeyPasswordGrantType -DtotalConcurrency=1000 -DrepeatTime=10 -DinjectTime=10
18 | ```
19 |
20 | -------------------------------------------------------------------
21 |
22 |
23 | ## JMeter 5.1 方式压力测试
24 |
25 | - 如果 JVM 不够可以修改 bin/jmeter 文件中的:`"${HEAP:="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"}"`
26 |
27 | ```
28 | cd /Users/youmeek/software/apache-jmeter-5.1.1/bin
29 |
30 | ./jmeter -n -t /Users/youmeek/TkeyPasswordGrantTypeJMeter.jmx -l /Users/youmeek/tkeyReport.jtl -e -o /Users/youmeek/htmlResult
31 | ```
32 |
33 | -------------------------------------------------------------------
34 |
35 | ## wrk 简单压力测试
36 |
37 |
38 | ```
39 | sudo yum groupinstall 'Development Tools'
40 | sudo yum install -y openssl-devel git
41 |
42 | git clone --depth=1 https://github.com/wg/wrk.git wrk
43 | cd wrk
44 | make
45 |
46 | sudo cp wrk /usr/local/bin
47 | ```
48 |
49 | ```
50 | wrk -t5 -c5 -d10s --script=/opt/post-wrk.lua --latency http://sso.cdk8s.com/sso/oauth/token
51 | ```
52 |
53 | - post-wrk.lua
54 |
55 | ```
56 | wrk.method = "POST"
57 | wrk.body = "grant_type=password&client_id=test_client_id_1&client_secret=test_client_secret_1&username=admin&password=123456"
58 | wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"
59 | ```
60 |
61 |
62 | -------------------------------------------------------------------
63 |
64 | ## 如何继续提高 QPS
65 |
66 | 在压力测试过程中我们用 JProfile 监控了 CPU 情况,具体如下图:
67 |
68 | 
69 |
70 | 经过上图我们已经有明确的答案:`checkClientIdParam()`
71 |
72 | 在校验 client 正确性的地方,读取了 redis,这个过程如果用二级缓存,经过我们压力测试可以再提高 15~20% 左右的 QPS。但是这样改造复杂度会提高,如果 TKey SSO Server 是多节点情况下,同步变更是个麻烦事,还要再引入 MQ,我觉得不划算。中小企业不建议为了这点性能提高系统复杂度。
73 |
74 | 对于中小企业发展,最核心的还是走对业务,能有一个随时掉头,变更方向的能力,所以系统复杂度一定要尽可能不高,或者契合当前企业的发展情况。
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/share-file/shell/runapp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # 记得给 sh 增加执行权限:chmod +x jar.sh
4 | pid=0
5 | ENV=test
6 | LOG_DATE=`date +%Y%m%d%H%M%S`
7 | APP_NAME=tkey-sso-server
8 | JAR_NAME=tkey-sso-server-1.0.0.jar
9 | APP_PATH=/data/jar/$APP_NAME
10 | APP_LOG_PATH=/data/jar/$APP_NAME/logs
11 |
12 | DUMP_PATH=$APP_PATH/headDump
13 | LOG_PATH=$APP_LOG_PATH/$APP_NAME.out
14 | JAR_FILE=$APP_PATH/$JAR_NAME
15 |
16 | APP_ENVIRONMENT="--SPRING_PROFILES_ACTIVE=$ENV --SERVER_PORT=9091 --SPRING_REDIS_HOST=redis.cdk8s.com --SPRING_REDIS_PASSWORD=123456 --TKEY_NODE_NUMBER=20"
17 |
18 | # JVM 参数
19 | JAVA_OPTS="$APP_ENVIRONMENT -Xms1024m -Xmx1024m -XX:MetaspaceSize=124m -XX:MaxMetaspaceSize=224m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$DUMP_PATH"
20 |
21 | # 支持远程 debug
22 | #JAVA_OPTS="$APP_ENVIRONMENT -Xms1024m -Xmx1024m -XX:MetaspaceSize=124m -XX:MaxMetaspaceSize=224m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$DUMP_PATH -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
23 |
24 |
25 | if [ ! -d $APP_LOG_PATH ]; then
26 | mkdir -p $APP_LOG_PATH
27 | fi
28 |
29 |
30 | start(){
31 | getpid
32 | if [ ! -n "$pid" ]; then
33 | nohup java -jar $JAR_FILE $JAVA_OPTS > $LOG_PATH 2>&1 &
34 | echo "----------------------------"
35 | echo "Application Startup Success"
36 | echo "----------------------------"
37 | sleep 2s
38 | tail -f $LOG_PATH
39 | else
40 | echo "$APP_NAME is runing PID: $pid"
41 | fi
42 |
43 | }
44 |
45 | status(){
46 | getpid
47 | if [ ! -n "$pid" ]; then
48 | echo "$APP_NAME not runing"
49 | else
50 | echo "$APP_NAME runing PID: $pid"
51 | fi
52 | }
53 |
54 | stop(){
55 | getpid
56 | if [ ! -n "$pid" ]; then
57 | echo "$APP_NAME not runing"
58 | else
59 | echo "$APP_NAME stop"
60 | kill -9 $pid
61 | fi
62 | }
63 |
64 | restart(){
65 | stop
66 | sleep 2s
67 | start
68 | }
69 |
70 | getpid(){
71 | pid=`ps -ef |grep $JAR_FILE |grep -v grep |awk '{print $2}'`
72 | }
73 |
74 | case $1 in
75 | start) start;;
76 | stop) stop;;
77 | restart) restart;;
78 | status) status;;
79 | *) echo "shell parameter: start|stop|restart|status" ;;
80 | esac
81 |
--------------------------------------------------------------------------------
/share-file/playbook/5-mysql-playbook.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | remote_user: root
3 | tasks:
4 | - name: remove the mariadb
5 | yum:
6 | name: mariadb
7 | state: absent
8 |
9 | - name: install mysql 1
10 | shell: "{{ item }}"
11 | with_items:
12 | - wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
13 | - yum localinstall -y mysql57-community-release-el7-11.noarch.rpm
14 |
15 | - name : install mysql 2
16 | yum:
17 | name: mysql-community-server
18 | async : 1000
19 | poll : 0
20 | register: mysql_install_result
21 |
22 | - name: 'check install result'
23 | async_status: jid={{ mysql_install_result.ansible_job_id }}
24 | register: job_mysql_install_result
25 | until: job_mysql_install_result.finished
26 | retries: 250
27 |
28 | - name: remove old /etc/my.cnf
29 | file:
30 | path: "/etc/my.cnf"
31 | state: absent
32 |
33 | - name: create my.cnf file
34 | file:
35 | path="/etc/{{ item }}"
36 | state=touch
37 | with_items:
38 | - my.cnf
39 |
40 | - name: set my.cnf
41 | blockinfile:
42 | path: /etc/my.cnf
43 | marker: ""
44 | block: |
45 | [mysql]
46 | default-character-set = utf8mb4
47 | [mysqld]
48 | max_connections = 500
49 | datadir = /var/lib/mysql
50 | socket = /var/lib/mysql/mysql.sock
51 | bind-address = 127.0.0.1
52 | symbolic-links=0
53 | log-error=/var/log/mysqld.log
54 | pid-file=/var/run/mysqld/mysqld.pid
55 | default-storage-engine = InnoDB
56 | collation-server = utf8mb4_unicode_520_ci
57 | init_connect = 'SET NAMES utf8mb4'
58 | character-set-server = utf8mb4
59 | lower_case_table_names = 1
60 | max_allowed_packet = 50M
61 | sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
62 |
63 | - name: enable mysql
64 | shell: "{{ item }}"
65 | with_items:
66 | - systemctl enable mysqld.service
67 | - systemctl restart mysqld.service
68 |
--------------------------------------------------------------------------------
/server/dev.md:
--------------------------------------------------------------------------------
1 |
2 | ## TKey 开发环境
3 |
4 | - 系统环境
5 | - macOS High Sierra 10.13.6
6 | - 后端
7 | - IntelliJ IDEA 2019.2
8 | - Oracle JDK 1.8.0_191
9 | - Maven 3.6.1
10 | - Redis 4(Docker Image)
11 | - Prometheus 2.11(Docker Image)
12 | - Grafana 6.2.5(Docker Image)
13 | - MySQL 5.7(Docker Image)
14 | - Postman 7.5.0
15 | - JMeter 5.1.1
16 | - Jenkins 2.176.2
17 | - JProfiler 11.0.1
18 | - Docker version 18.09.2
19 | - Docker Desktop 2.0.0.3
20 | - 前端
21 | - WebStorm 2019.2
22 | - Node 10.14.2
23 | - npm 6.4.1
24 | - Yarn 1.12.3
25 |
26 | ## TKey 项目核心组件版本(版本号 pom.xml 为准)
27 |
28 | - 依赖包完整列表 [pom.xml](https://github.com/cdk8s/tkey/blob/master/pom.xml)
29 | - 核心:`Spring Boot 2.1.7.RELEASE`
30 | - 其他(后续以 pom.xml 文件为主):
31 |
32 | ```
33 | 3.8.1
34 | 1.5
35 | 4.2
36 | 2.6
37 | 1.11
38 |
39 | 27.0.1-jre
40 | 3.12.1
41 | 4.5.13
42 | ```
43 |
44 |
45 |
46 | ## 推荐使用 Postman 进行尝试性的接口测试
47 |
48 |
49 | - Postman 的设置 302 重定向:`Settings > General > Automatically follow redirects`
50 |
51 | 默认是:ON,如果需要查看 302 的跳转中间状态,需要关闭为 OFF,不然在调试的时候如果客户端服务已经关闭,则只会看到报错信息,但是不知道是具体什么报错。
52 |
53 | - Postman 导入我们已经准备好的请求参数,避免你直接摸索
54 |
55 | 链接地址:
56 |
57 | - [Postman 导入 TKey 接口集方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-import-link.gif)
58 | - [Postman 接口转 cURL 方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-to-curl.gif)
59 |
60 | ## Docker 环境
61 |
62 | - 如果你还没有 Docker 环境,建议查看我们此系列教程:[CentOS 操作系统](https://github.com/cdk8s/cdk8s-team-style/tree/master/os/linux)
63 | - TKey SSO Server 需要 Redis,Redis 信息可以在该文件进行修改:`application-dev.yml`
64 |
65 | ## 核心的用户校验逻辑
66 |
67 | - 在 OauthController.java 类中
68 | - 这里采用的是 REST API 校验,如果你们要直连数据库,可以在改写该逻辑
69 | - 至于为什么要这么设计,已经在下面文章进行了说明
70 | - 故意设计点(常见问题):[Github](https://github.com/cdk8s/tkey-docs/blob/master/faq/README.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/faq/README.md)
71 |
72 |
73 | ```
74 | OauthUserAttribute oauthUserAttribute = requestLoginApi(oauthFormLoginParam);
75 | ```
76 |
77 | ## 登录页面改造
78 |
79 | - TKey SSO Server 没有采用前后端分离,目前考虑是没有必要,就一个登录页面
80 | - 使用的是 Thymeleaf 模板引擎
81 | - 登录页面路径:`/resources/templates/login.html`
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/share-file/playbook/6-redis-playbook.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | remote_user: root
3 | tasks:
4 | - name: install redis
5 | yum:
6 | name: redis
7 |
8 | - name: remove old /etc/redis.conf
9 | file:
10 | path: "/etc/redis.conf"
11 | state: absent
12 |
13 | - name: create /etc/redis.conf file
14 | file:
15 | path="/etc/{{ item }}"
16 | state=touch
17 | mode=777
18 | with_items:
19 | - redis.conf
20 |
21 | - name: set redis.conf
22 | blockinfile:
23 | path: /etc/redis.conf
24 | marker: ""
25 | block: |
26 | bind 0.0.0.0
27 | requirepass adgredis123456
28 | protected-mode yes
29 | port 6379
30 | tcp-backlog 511
31 | timeout 0
32 | tcp-keepalive 300
33 | daemonize no
34 | supervised no
35 | pidfile /var/run/redis_6379.pid
36 | loglevel notice
37 | logfile /var/log/redis/redis.log
38 | databases 16
39 | save 900 1
40 | save 300 10
41 | save 60 10000
42 | stop-writes-on-bgsave-error yes
43 | rdbcompression yes
44 | rdbchecksum yes
45 | dbfilename dump.rdb
46 | dir /var/lib/redis
47 | slave-serve-stale-data yes
48 | slave-read-only yes
49 | repl-diskless-sync no
50 | repl-diskless-sync-delay 5
51 | repl-disable-tcp-nodelay no
52 | slave-priority 100
53 | appendonly no
54 | appendfilename "appendonly.aof"
55 | appendfsync everysec
56 | no-appendfsync-on-rewrite no
57 | auto-aof-rewrite-percentage 100
58 | auto-aof-rewrite-min-size 64mb
59 | aof-load-truncated yes
60 | lua-time-limit 5000
61 | slowlog-log-slower-than 10000
62 | slowlog-max-len 128
63 | latency-monitor-threshold 0
64 | notify-keyspace-events ""
65 | hash-max-ziplist-entries 512
66 | hash-max-ziplist-value 64
67 | list-max-ziplist-size -2
68 | list-compress-depth 0
69 | set-max-intset-entries 512
70 | zset-max-ziplist-entries 128
71 | zset-max-ziplist-value 64
72 | hll-sparse-max-bytes 3000
73 | activerehashing yes
74 | client-output-buffer-limit normal 0 0 0
75 | client-output-buffer-limit slave 256mb 64mb 60
76 | client-output-buffer-limit pubsub 32mb 8mb 60
77 | hz 10
78 | aof-rewrite-incremental-fsync yes
79 |
80 | - name: enable redis
81 | shell: "{{ item }}"
82 | with_items:
83 | - systemctl enable redis
84 | - systemctl restart redis
85 |
--------------------------------------------------------------------------------
/share-file/playbook/1-install-basic-playbook.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | remote_user: root
3 | tasks:
4 | - name: Disable SELinux at next reboot
5 | selinux:
6 | state: disabled
7 |
8 | - name: disable firewalld
9 | command: "{{ item }}"
10 | with_items:
11 | - systemctl stop firewalld
12 | - systemctl disable firewalld
13 | - echo "vm.swappiness = 0" >> /etc/sysctl.conf
14 | - swapoff -a
15 | - sysctl -w vm.swappiness=0
16 |
17 | - name: install-epel
18 | command: "{{ item }}"
19 | with_items:
20 | - yum install -y epel-release
21 |
22 | - name: install-basic
23 | command: "{{ item }}"
24 | with_items:
25 | - yum install -y zip unzip lrzsz git wget htop deltarpm
26 |
27 | - name: install zsh oh-my-zsh
28 | shell: "{{ item }}"
29 | with_items:
30 | - yum install -y zsh
31 | - wget https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh -O - | sh
32 | - chsh -s /bin/zsh root
33 |
34 | - name: install zsh plugin
35 | shell: "{{ item }}"
36 | with_items:
37 | - git clone https://github.com/zsh-users/zsh-autosuggestions.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
38 | - git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
39 |
40 | - name: replace zshrc theme
41 | lineinfile:
42 | path: /root/.zshrc
43 | regexp: '^ZSH_THEME='
44 | line: ZSH_THEME="af-magic"
45 |
46 | - name: replace zshrc plugins
47 | lineinfile:
48 | path: /root/.zshrc
49 | regexp: '^plugins='
50 | line: plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
51 |
52 |
53 | - name: install-vim
54 | shell: "{{ item }}"
55 | with_items:
56 | - yum install -y vim
57 | - curl https://raw.githubusercontent.com/wklken/vim-for-server/master/vimrc > ~/.vimrc
58 |
59 | - name: install-docker
60 | shell: "{{ item }}"
61 | with_items:
62 | - yum install -y yum-utils device-mapper-persistent-data lvm2
63 | - yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
64 | - yum makecache fast
65 | - yum install -y docker-ce docker-ce-cli containerd.io
66 | - systemctl start docker.service
67 |
68 | - name: create /etc/docker directory
69 | file:
70 | path: /etc/docker
71 | state: directory
72 |
73 | - name: create daemon.json file
74 | file:
75 | path=/etc/docker/{{ item }}
76 | state=touch
77 | mode=777
78 | with_items:
79 | - daemon.json
80 |
81 | - name: set docker registry mirrors
82 | blockinfile:
83 | path: /etc/docker/daemon.json
84 | marker: ""
85 | block: |
86 | {
87 | "registry-mirrors": [
88 | "https://ldhc17y9.mirror.aliyuncs.com",
89 | "https://hub-mirror.c.163.com",
90 | "https://mirror.baidubce.com",
91 | "https://docker.mirrors.ustc.edu.cn"
92 | ]
93 | }
94 |
95 | - name: restart docekr
96 | shell: "{{ item }}"
97 | with_items:
98 | - systemctl daemon-reload
99 | - systemctl restart docker
100 |
101 | - name: install-docker-compose
102 | shell: "{{ item }}"
103 | with_items:
104 | - curl -L https://get.daocloud.io/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
105 | - chmod +x /usr/local/bin/docker-compose
106 | - docker-compose --version
107 | - systemctl restart docker.service
108 | - systemctl enable docker.service
109 |
--------------------------------------------------------------------------------
/server/oauth-grant-type/code.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Postman 接口集分享
4 |
5 | - 链接地址:
6 | - [Postman 导入 TKey 接口集方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-import-link.gif)
7 | - [Postman 接口转 cURL 方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-to-curl.gif)
8 |
9 | ## 授权码模式
10 |
11 |
12 | ### 用户未认证,跳转登录页面
13 |
14 | - **GET 请求**(业务系统重定向)
15 | - 请求地址:
16 | - URL 参数
17 |
18 | ```
19 | response_type: code
20 | client_id: test_client_id_1
21 | redirect_uri: http://test1.cdk8s.com:9393/client-scribejava/user?id=123456&name=cdk8s
22 | state: 12345
23 | ```
24 |
25 | - 完整 demo:
26 |
27 | ```
28 | http://sso.cdk8s.com:9091/sso/oauth/authorize?response_type=code&client_id=test_client_id_1&redirect_uri=http%3A%2F%2Ftest1.cdk8s.com%3A9393%2Fclient-scribejava%2FcodeCallback%3Fredirect_uri%3Dhttp%253A%252F%252Ftest1.cdk8s.com%253A9393%252Fclient-scribejava%252Fuser%253Fid%253D123456%2526name%253Dcdk8s
29 | ```
30 |
31 | - 其中,最让人看不懂的是:`http%3A%2F%2Ftest1.cdk8s.com%3A9393%2Fclient-scribejava%2FcodeCallback%3Fredirect_uri%3Dhttp%253A%252F%252Ftest1.cdk8s.com%253A9393%252Fclient-scribejava%252Fuser%253Fid%253D123456%2526name%253Dcdk8s`
32 | - 这里进行了 URL 转码
33 | - 其中还有一个子参数:`%3Fredirect_uri%3Dhttp%253A%252F%252Ftest1.cdk8s.com%253A9393%252Fclient-scribejava%252Fuser%253Fid%253D123456%2526name%253Dcdk8s`
34 | - 该参数也进行了一个 URL 转码
35 | - 这个地址也就是用户最终登录后的跳转地址
36 | - Spring Security 的客户端没有这种情况,是因为它内部做了 cookie 的映射,所以最终重定向的地址不是根据 url 参数来的
37 | - 我们封装的 tkey-sso-client-scribejava 则是完全根据 url 参数来做最后登录成功的跳转
38 | - state 可以为空
39 |
40 |
41 | ### 用户提交的用户名和密码不匹配
42 |
43 | - 停留在登录页面,显示登录错误信息
44 |
45 | ### 用户提交的用户名和密码匹配
46 |
47 | - 301 重定向到:`http://test1.cdk8s.com:9393/client-scribejava/codeCallback?redirect_uri=http%3A%2F%2Ftest1.cdk8s.com%3A9393%2Fclient-scribejava%2Fuser%3Fid%3D123456%26name%3Dcdk8s`
48 |
49 | -------------------------------------------------------------------
50 |
51 | ## 业务系统回调接口触发授权码第二步,通过 code 换取 token(核心点)
52 |
53 | - **POST 请求**
54 | - 请求地址:
55 | - 参数:
56 |
57 | ```
58 | grant_type: authorization_code
59 | code: OC-106-uUddPxoWCEa4NBO5GaVIRJOTZLlWbHNr
60 | redirect_uri: http://test1.cdk8s.com:9393/client-scribejava/user?id=123456&name=cdk8s
61 | client_id: test_client_id_1
62 | client_secret: test_client_secret_1
63 | ```
64 |
65 |
66 | ### 请求参数合法,系统返回
67 |
68 | - 状态码 200
69 | - JSON 数据
70 |
71 | ```
72 | {
73 | "access_token": "AT-MISqrbWUxFWc1xU4e8JK2OcMgJYusF22-101",
74 | "token_type": "Bearer",
75 | "expires_in": 57600,
76 | "refresh_token": "RT-7UPY41g9j5K8rKBZse4qo4iP6sAbU2Df-102"
77 | }
78 | ```
79 |
80 | ### 请求参数不合法,系统返回
81 |
82 | - 状态码 400
83 | - JSON 数据
84 |
85 | ```
86 | {
87 | "error": "invalid request",
88 | "error_description": "请求类型不匹配",
89 | "error_uri_msg": "See the full API docs at https://github.com/cdk8s"
90 | }
91 | ```
92 |
93 | -------------------------------------------------------------------
94 |
95 |
96 | ## 业务系统通过 access_token 换取用户信息(核心点)
97 |
98 | - **GET 请求**
99 | - 请求地址:
100 | - 参数:
101 |
102 | ```
103 | access_token: AT-dJTLEsFLR2PbxU1l8GPx3CUS9O3Lhzdn-102
104 | ```
105 |
106 |
107 | ### 请求参数合法,系统返回
108 |
109 | - 状态码 200
110 | - JSON 数据
111 |
112 | ```
113 | {
114 | "username": "admin",
115 | "name": "admin",
116 | "id": "111222333",
117 | "user_id": "111222333",
118 | "user_attribute": {
119 | "email": "admin@cdk8s.com",
120 | "user_id": "111222333",
121 | "username": "admin"
122 | },
123 | "grant_type": "authorization_code",
124 | "client_id": "test_client_id_1",
125 | "iat": 1562134212,
126 | "exp": 1562191812
127 | }
128 | ```
129 |
130 | ### 请求参数不合法,系统返回
131 |
132 | - 状态码 400
133 | - JSON 数据
134 |
135 | ```
136 | {
137 | "error": "invalid request",
138 | "error_description": "请求类型不匹配",
139 | "error_uri_msg": "See the full API docs at https://github.com/cdk8s"
140 | }
141 | ```
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/server/oauth-grant-type/common.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## Postman 接口集分享
5 |
6 | - 链接地址:
7 | - [Postman 导入 TKey 接口集方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-import-link.gif)
8 | - [Postman 接口转 cURL 方法(Gif 动图)](http://img.gitnavi.com/tkey/postman-to-curl.gif)
9 |
10 | -------------------------------------------------------------------
11 |
12 |
13 | ## 获取 access_token 对应的用户信息
14 |
15 | - **POST 请求**
16 | - 请求地址:
17 | - 参数方式
18 | - 请求头带有:`Authorization: Bearer AT-102-dJTLEsFLR2PbxU1l8GPx3CUS9O3Lhzdn`
19 |
20 | - **GET 请求**
21 | - 请求地址:
22 |
23 |
24 | ### 请求参数合法,系统返回
25 |
26 | - 状态码 200
27 | - JSON 数据(不带用户信息)
28 |
29 | ```
30 | {
31 | "user_attribute": {},
32 | "grant_type": "client_credentials",
33 | "iat": 1451602800,
34 | "exp": 1451606400,
35 | "client_id": "test_client_id_1"
36 | }
37 | ```
38 |
39 |
40 | - JSON 数据(带用户信息)
41 |
42 | ```
43 | {
44 | "user_attribute": {
45 | "email": "gitnavi@youmeek.com",
46 | "user_id": "7172",
47 | "username": "张三"
48 | },
49 | "grant_type": "authorization_code",
50 | "iat": 1451602800,
51 | "exp": 1451606400,
52 | "client_id": "test_client_id_1"
53 | }
54 |
55 | ```
56 |
57 | ### 请求参数不合法,系统返回
58 |
59 | - 状态码 400
60 | - JSON 数据
61 |
62 | ```
63 | {
64 | "error": "invalid request",
65 | "error_description": "请求类型不匹配",
66 | "error_uri_msg": "See the full API docs at https://github.com/cdk8s"
67 | }
68 | ```
69 |
70 |
71 | -------------------------------------------------------------------
72 |
73 | ## 登出
74 |
75 | - **GET 请求**
76 | - 请求地址:
77 |
78 |
79 | ### 请求参数合法,系统返回
80 |
81 | - 状态码 302
82 | - Location
83 |
84 | ```
85 | http://test1.cdk8s.com:9393/client-scribejava
86 | ```
87 |
88 |
89 | ### 请求参数不合法,系统返回
90 |
91 | - 停留在登录页面或跳转到 error 页面
92 |
93 |
94 | -------------------------------------------------------------------
95 |
96 |
97 | ## 通过 refresh_token,获取新的 access_token
98 |
99 |
100 | - **POST 请求**
101 | - 请求地址:
102 | - 参数:
103 |
104 | ```
105 | grant_type: refresh_token
106 | refresh_token: RT-8aI3zHbArcmzT3ukHlBQ88AdMv2NB8Aa-103
107 | client_id: test_client_id_1
108 | client_secret: test_client_secret_1
109 | ```
110 |
111 | ### cURL
112 |
113 | ```
114 | curl -X POST \
115 | http://sso.cdk8s.com:9091/sso/oauth/token \
116 | -H 'Content-Type: application/x-www-form-urlencoded' \
117 | -H 'cache-control: no-cache' \
118 | -d 'grant_type=refresh_token&refresh_token=RT-8aI3zHbArcmzT3ukHlBQ88AdMv2NB8Aa-103&client_id=test_client_id_1&client_secret=test_client_secret_1'
119 | ```
120 |
121 |
122 | ### 请求参数合法,系统返回
123 |
124 | - 状态码 200
125 | - JSON 数据
126 |
127 | ```
128 | {
129 | "access_token": "AT-IDm312Our5Jti70BGE8RgO2qRK29blri",
130 | "token_type": "Bearer",
131 | "expires_in": 57600
132 | }
133 | ```
134 |
135 | ### 请求参数不合法,系统返回
136 |
137 | - 状态码 400
138 | - JSON 数据
139 |
140 | ```
141 | {
142 | "error": "invalid request",
143 | "error_description": "请求类型不匹配",
144 | "error_uri_msg": "See the full API docs at https://github.com/cdk8s"
145 | }
146 | ```
147 |
148 |
149 | -------------------------------------------------------------------
150 |
151 |
152 | ## 验证 access_token / refresh_token
153 |
154 |
155 | - **POST 请求**
156 | - 请求地址:
157 | - 参数:
158 |
159 | ```
160 | client_id: test_client_id_1
161 | client_secret: test_client_secret_1
162 | token: AT-3KGHVaANf4Ppi1IhrlHTF9IKSsV7fuzY-109
163 | token_type_hint: access_token
164 | ```
165 |
166 | - token_type_hint,可选值
167 | - `access_token`
168 | - `refresh_token`
169 |
170 | ### 请求参数合法,系统返回
171 |
172 | - 状态码 200
173 | - JSON 数据
174 |
175 | ```
176 | {
177 | "token_type": "Bearer",
178 | "grant_type": "client_credentials",
179 | "client_id": "test_client_id_1",
180 | "exp": 1561438626,
181 | "iat": 1561381026
182 | }
183 | ```
184 |
185 |
186 | ###### 请求参数不合法,系统返回
187 |
188 | - 状态码 400
189 | - JSON 数据
190 |
191 | ```
192 | {
193 | "error": "invalid request",
194 | "error_description": "请求类型不匹配",
195 | "error_uri_msg": "See the full API docs at https://github.com/cdk8s"
196 | }
197 | ```
198 |
199 | -------------------------------------------------------------------
200 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # This file is inspired by https://github.com/alexkaratarakis/gitattributes
2 | #
3 | # Auto detect text files and perform LF normalization
4 | # http://davidlaing.com/2012/09/19/customise-your-gitattributes-to-become-a-git-ninja/
5 | * text=auto
6 |
7 | # The above will handle all files NOT found below
8 | # These files are text and should be normalized (Convert crlf => lf)
9 |
10 | # Java sources
11 | *.java text diff=java
12 | *.gradle text diff=java
13 | *.gradle.kts text diff=java
14 |
15 |
16 | *.css text diff=css
17 | *.htm text diff=html
18 | *.html text diff=html
19 | *.xhtml text diff=html
20 | *.coffee text
21 | *.cql text
22 | *.df text
23 | *.ejs text
24 | *.js text
25 | *.jsx text
26 | *.json text
27 | *.less text
28 | *.properties text
29 | *.sass text
30 | *.scss text diff=css
31 | *.sh text eol=lf
32 | *.sql text
33 | *.txt text
34 | *.ts text
35 | *.tsx text
36 | *.xml text
37 | *.yaml text
38 | *.yml text
39 | *.jsp text
40 | *.jspf text
41 | *.jspx text
42 | *.tld text
43 | *.tag text
44 | *.tagx text
45 | *.inc text
46 | *.ini text
47 |
48 | # Documents
49 | *.doc diff=astextplain
50 | *.DOC diff=astextplain
51 | *.docx diff=astextplain
52 | *.DOCX diff=astextplain
53 | *.dot diff=astextplain
54 | *.DOT diff=astextplain
55 | *.pdf diff=astextplain
56 | *.PDF diff=astextplain
57 | *.rtf diff=astextplain
58 | *.RTF diff=astextplain
59 | *.markdown text
60 | *.md text
61 | *.adoc text
62 | *.textile text
63 | *.mustache text
64 | *.csv text
65 | *.tab text
66 | *.tsv text
67 | *.txt text
68 | AUTHORS text
69 | CHANGELOG text
70 | CHANGES text
71 | CONTRIBUTING text
72 | COPYING text
73 | copyright text
74 | *COPYRIGHT* text
75 | INSTALL text
76 | license text
77 | LICENSE text
78 | NEWS text
79 | readme text
80 | *README* text
81 | TODO text
82 |
83 | # Graphics
84 | *.png binary
85 | *.jpg binary
86 | *.jpeg binary
87 | *.gif binary
88 | *.tif binary
89 | *.tiff binary
90 | *.ico binary
91 |
92 | # SVG treated as an asset (binary) by default. If you want to treat it as text,
93 | # comment-out the following line and uncomment the line after.
94 | *.svg binary
95 | #*.svg text
96 | *.eps binary
97 |
98 | # These files are binary and should be left untouched
99 | # (binary is a macro for -text -diff)
100 | *.class binary
101 | *.jar binary
102 | *.war binary
103 | *.dll binary
104 | *.ear binary
105 | *.so binary
106 | *.exe binary
107 | *.pyc binary
108 |
109 | ## LINTERS
110 | .csslintrc text
111 | .eslintrc text
112 | .jscsrc text
113 | .jshintrc text
114 | .jshintignore text
115 | .stylelintrc text
116 |
117 | ## CONFIGS
118 | *.conf text
119 | *.config text
120 | .editorconfig text
121 | .gitattributes text
122 | .gitconfig text
123 | .gitignore text
124 | .htaccess text
125 | *.npmignore text
126 |
127 | ## HEROKU
128 | Procfile text
129 | .slugignore text
130 |
131 | ## AUDIO
132 | *.kar binary
133 | *.m4a binary
134 | *.mid binary
135 | *.midi binary
136 | *.mp3 binary
137 | *.ogg binary
138 | *.ra binary
139 |
140 | ## VIDEO
141 | *.3gpp binary
142 | *.3gp binary
143 | *.as binary
144 | *.asf binary
145 | *.asx binary
146 | *.fla binary
147 | *.flv binary
148 | *.m4v binary
149 | *.mng binary
150 | *.mov binary
151 | *.mp4 binary
152 | *.mpeg binary
153 | *.mpg binary
154 | *.swc binary
155 | *.swf binary
156 | *.webm binary
157 |
158 | ## ARCHIVES
159 | *.7z binary
160 | *.7z binary
161 | *.gz binary
162 | *.rar binary
163 | *.tar binary
164 | *.zip binary
165 |
166 | ## FONTS
167 | *.ttf binary
168 | *.eot binary
169 | *.otf binary
170 | *.woff binary
171 | *.woff2 binary
172 |
173 |
174 | *.bash text eol=lf
175 | *.bat text eol=crlf
176 | *.cmd text eol=crlf
177 |
178 |
179 | *.php text diff=php
180 | *.py text diff=python
181 | *.rb text diff=ruby
182 |
183 | # Docker
184 | *.dockerignore text
185 | Dockerfile text
186 |
187 |
188 |
--------------------------------------------------------------------------------
/faq/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## TKey SSO Server
3 |
4 |
5 | - 大部分场景下的设计都是有原因,我说说我们的考虑
6 |
7 |
8 | ## 关于 Token 命名与格式
9 |
10 | - 在命名上借鉴了 CAS,比如:AT-,RT-,OC-,TGC 这类都是来源 CAS。
11 | - OAuth 2.0 没有规定 token 的命名,你如果不喜欢也可以自己改造下。
12 | - 关于 Bearer 和 Authorization 这两个关键字,规范中没有明确要求要不要区分大小写。但是从业界使用情况看,我们一般都建议首字母大写。TKey 虽然在大小写上也做了兼容,但是建议大家还是首字母大写。
13 |
14 |
15 | ## 为什么用户认证是通过 REST API 而不是数据库
16 |
17 | 会 Spring Boot 的人自己加个 Mapper 之后去查数据库,这个真的不难吧。
18 |
19 | 但是我这样设计是有原因的。
20 |
21 | 有很多企业的用户体系其实起步已经很早了,可能是用 Oracle、MSSQL、LDAP 等等,如果你很幸运,刚好是 MySQL 那确实稍微改一下就可以了。
22 |
23 | 可是现实中很多企业不是,而我又不想 TKey 引入太多内容,所以我建议是那些老系统开放出 REST API,TKey 通过内网方式调用老系统验证用户信息。
24 |
25 | ## 为什么 code 只能用一次
26 |
27 | 标准虽然没有强制规定 code 能用多少次,但是从安全角度来讲,以及业界大家使用上目前都是 code 只能被使用一次。
28 |
29 | 如果你们对此有需求可以在:`OauthCodeToTokenStrategy.java` 中找到该代码进行调整:
30 |
31 | ```
32 | codeRedisService.delete(oauthTokenParam.getCode());
33 | ```
34 |
35 |
36 | ## 为什么引入 Redis
37 |
38 | 大家如果看过 TKey 的压力测试文档内容,会知道目前主要的瓶颈开销在 Redis 连接和存取上。
39 |
40 | 可是,我是坚定要上存储介质的,可以不是 Redis,可以换成:LevelDB、SSDB、RocksDB、Memcached 等等。但是必然要有一个存储介质来存储 Token 信息。不然无法解决任意横向扩展 TKey 服务这件事。
41 |
42 | 也因为引入了 Redis,所以 TKey 的维护就变成异常简单,因为它无状态,想停就停,想启动就启动。我们只要维护好:Redis 的高可用,保持好网络通畅。
43 |
44 | 小公司自己维护 Redis 没什么问题,因为量不大。如果公司已经成规模,建议直接采用云上 Redis,尽可能保住高可用。
45 |
46 |
47 | ## OAuth 2.0 Token 请求参数的 3 种方式
48 |
49 | 按 OAuth 2.0 的标准,要使用 Token 有 3 种方式:
50 |
51 | - 使用 HTTP Authorization 头部(优先推荐)
52 | - 使用表单格式的请求体参数
53 | - 使用 URL 编码的查询参数
54 |
55 | 优先推荐请求头方式或 POST 表单,因为 URL 比较容易被日志监控中拿到。
56 |
57 | 如果我部分文档或测试采用 URL 方式,那只有一个原因:为了方便。大家不要学习这种行为。
58 |
59 | 目前 3 种模式我都做了支持,但是优先推荐请求头。
60 |
61 |
62 | ## 刷新 Token 接口的返回 JSON 内容
63 |
64 | 刷新 Token 接口目前 TKey 返回内容格式是这样的:
65 |
66 | ```
67 | {
68 | "access_token": "AT-101-IDm312Our5Jti70BGE8RgO2qRK29blri",
69 | "token_type": "Bearer",
70 | "expires_in": 57600
71 | }
72 | ```
73 |
74 | 但是,业界还有一种玩法,在给了新 AccessToken 之后,重新给你一个新的 RefreshToken,我个人是觉得没必要,所以不对这种玩法进行支持。
75 |
76 | ```
77 | {
78 | "access_token": "AT-IDm312Our5Jti70BGE8RgO2qRK29blri-101",
79 | "refresh_token": "RT-8aI3zHbArcmzT3ukHlBQ88AdMv2NB8Aa-103",
80 | "token_type": "Bearer",
81 | "expires_in": 57600
82 | }
83 | ```
84 |
85 | ## 功能开关
86 |
87 | - 由于目前功能相对单一,所以暂时不设置任何功能开关,后期版本迭代多了必然要上功能开关。
88 | - 同时也建议在开发系统的时候注重这一块的设计,不然维护起来成本会大很多。
89 |
90 | ## 为什么选择 Prometheus
91 |
92 | - InfluxDB 挺好的
93 | - 但是,后面要上 K8S,不想扩展出多个时序库,所以就选择了 Prometheus
94 |
95 | ## Actuator
96 |
97 | Spring Boot 可以借用 Spring Security 来实现 Actuator 的访问认证,但是为了方便 Prometheus 拉取数据,这里并没有这样设计。所以目前 actuator 是完全裸奔的。
98 |
99 | 建议是不对外开放 IP 访问,或者在 Nginx 配置上该路径的 Basic Auth,避免信息泄露。
100 |
101 |
102 | ## TKey 的 userinfo 接口返回的用户信息为何冗余
103 |
104 |
105 | 在每个系统中,用户唯一主键叫什么名字都是不一样的,有人叫:id,userid,user_id,id_ 等等等
106 |
107 | 而用户信息根对象中必须要有一个主键,我这里借鉴了 Spring Security 的 FixedPrincipalExtractor.java 类。它限定了这几个:`user`、`username`、`userid`、`user_id`、`login`、`id`、`name`。所以我也为了做兼容冗余了部分字段。
108 |
109 |
110 | ## ApplicationTestDataInitRunner.java 的作用
111 |
112 |
113 | 为了方便测试,我会在该类有一个初始化预设几个 code 和 token 的动作,虽然已经在开头限制了:`@Profile({"dev", "gatling", "test", "junit"})`
114 |
115 | 但是,还是提醒大家上生产的时候要注意这个细节。
116 |
117 | ## 为什么没有 scope 设计
118 |
119 | OAuth 很核心的点就是 scope,但是我在这个版本没有考虑。因为我目的很明确,就是为了做单点登录,并且初期还不是开放平台方式的那种单点登录。所以,如果加上 scope 设计,整个登录过程会过于冗余。
120 |
121 | 当然,我们也可以设计该功能,然后做上开关。只是暂时不是我们的优先级。
122 |
123 | 内部系统的授权一般建议交给 API 网关统一处理。
124 |
125 | 如果你目前就有scope 的需求,那我建议你自行先改造。按 OAuth 2.0 规范,scope 的设计是用空格隔开的,比如:`read write delete`
126 |
127 | ## 为什么没有 找回密码、修改密码功能
128 |
129 | 找回密码和修改密码是 UPMS 管的,不应该是 SSO 的事情,只是登录页面可以放个链接跳转到 UPMS 系统去而已。
130 |
131 |
132 | ## 为什么没有单点登出
133 |
134 | 单点登出分两种业务场景:
135 |
136 | - 1. 从某个业务系统登出,其他已经登录过的业务系统不做变更,要访问的新系统则需要重新登录
137 | - 2. 从某个业务系统登出,其他已经登录过的业务系统也跟着退出
138 |
139 | 第一种业务场景比较好理解。
140 |
141 | 第二种业务场景又可以分为两种情况:
142 |
143 | - 1. 有 API 网关
144 | - 2. 没有 API 网关
145 |
146 | 如果有 API 网关,在任何业务系统退出,本质就是网关上退出,那你下次访问任何业务系统肯定都是要重新登录
147 |
148 | 如果没有 API 网关,则这里就要引入 MQ 或则 RPC 通信。每个业务系统监听 TKey 的 MQ 通道,当发现各自的业务系统中有当前退出用户的 Token 则要自己进行销毁。但是这样的设计复杂度就上来了,不划算。所以,这里又一次提到了 API 网关,API 网关真的很重要。
149 |
150 | 还有一种适合小企业的办法。就是 TKey 和业务系统都用同一个 Redis,然后 TKey 再新增加维护一个新的 Key 规则:`userId : 所有业务系统生成过的 Token 集合`。这样,当某个业务系统退出,TKey 就可以通过 userId 找到所有 Token 进行删除。但是,感觉这样的企业应该很少,都要上单点登录了,应该规模还可以,不应该同用一个 Redis...
151 |
152 |
153 |
154 | ## 为什么 TKey SSO Client Java 那么多版本
155 |
156 | 考虑到有些业务系统已经用 Spring Security 的,为了使得改造成本尽可能减小,所以这里做了 demo 实例。
157 |
158 | 其中 Spring Security 在 4 和 5 版本上本身做了的大修改,所以我这边做了两个 demo 来区分开。
159 |
160 | - 在 Spring Boot 1.5.x 中使用的是 Spring Security 4
161 | - 在 Spring Boot 2.1.x 中使用的是 Spring Security 5
162 |
163 | 但是,如果觉得不管怎么改造都有成本,那我建议参考我自己写 REST Client demo,这有助于你后期各种需求下的玩法。
164 |
165 |
166 | ## 前后端分离要注意什么
167 |
168 | 前后端分离分为两种场景:
169 |
170 | - 1. 前后端的域名只是二级目录不一致,或者三级域名不一致
171 | - 2. 前后端的域名完全不一致
172 |
173 | 第一种情况还可以采用 Cookie、Session 的方式维护,虽然不推荐,但是确实是可以这样做的。
174 |
175 | 第二种情况 Cookie、Session 是完全用不了的,只能把 Token 信息交给前端存储在 LocalStorage、SessionStorage 中,请求的时候带上请求头。推荐大家使用这种。
176 |
177 | 但是这里有一个小细节,如果使用我们的 TKey Client,则 `enable-code-callback-to-front: true` 必须是 true。表示 code 的回调在前端接收,然后前端再交给业务后端去调用 TKey,不然整个过程,你前端与后端是没有任何交流的,也就拿不到最后业务后端的 Token。所以才有这一步的设计。但是我个人觉得不够优雅,如果大家有跟优雅的方式,赶紧联系我们~
178 |
179 |
180 | ## 密码模式的常用场景分析
181 |
182 | - 默认是采用授权码模式,要来回跳转。虽然这样会安全一点,但是有些环境可能不需要那么安全,只要方便就行,比如小程序、APP 那我推荐使用密码模式。
183 | - 假设场景如下:这类前端一般都有自己的登录页面,页面上用户和密码是传给业务系统,业务系统采用密码模式调用 TKey Server 获取到 Token 信息,然后返回 JSON 信息给前端,前端可以存储到 Session Storage 中。
184 |
185 |
186 | ## 刷新 Token 如何使用
187 |
188 | 如果你们的业务系统都是在 PC 上,那其实我觉得可以不考虑,因为 TGC 的有效期很长,特别是勾选了记住我之后,默认有 7 天的时间,在这个过程中,只要用户不清除缓存、Cookie,则每次访问业务系统都会生成新的 AccessToken。
189 |
190 | 这时候用不用 RefreshToken 都无所谓了。
191 |
192 | 但是如果你们有移动端的业务场景,那就需要考虑移动端用户通过 RefreshToken 自动帮用户刷新的 Token 进行使用。
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
--------------------------------------------------------------------------------
/share-file/playbook/3-maven-playbook.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | remote_user: root
3 | vars:
4 | maven_install_folder: /usr/local
5 | file_name: apache-maven-3.6.3-bin.zip
6 | tasks:
7 | - name: copy maven
8 | copy:
9 | src=/opt/{{ file_name }}
10 | dest={{ maven_install_folder }}
11 |
12 | - name: unzip maven
13 | shell:
14 | chdir={{ maven_install_folder }}
15 | unzip {{ file_name }}
16 |
17 | - name: set MAVEN_HOME
18 | blockinfile:
19 | path: /root/.zshrc
20 | marker: "#{mark} MAVEN ENV"
21 | block: |
22 | MAVEN_HOME={{ maven_install_folder }}/apache-maven-3.6.3
23 | M3_HOME={{ maven_install_folder }}/apache-maven-3.6.3
24 | M2_HOME={{ maven_install_folder }}/apache-maven-3.6.3
25 | PATH=$PATH:$M3_HOME/bin
26 | MAVEN_OPTS="-Xms256m -Xmx356m"
27 | export M3_HOME
28 | export M2_HOME
29 | export MAVEN_HOME
30 | export PATH
31 | export MAVEN_OPTS
32 |
33 | - name: source zshrc
34 | shell: source /root/.zshrc
35 |
36 | - name: remove zip file
37 | file:
38 | path: "{{ maven_install_folder }}/{{ file_name }}"
39 | state: absent
40 |
41 | - name: create local_maven_repository directory
42 | file:
43 | path: /opt/local_maven_repository
44 | state: directory
45 |
46 | - name: remove old settings.xml
47 | file:
48 | path: "{{ maven_install_folder }}/apache-maven-3.6.3/conf/settings.xml"
49 | state: absent
50 |
51 | - name: create settings.xml file
52 | file:
53 | path="{{ maven_install_folder }}/apache-maven-3.6.3/conf/{{ item }}"
54 | state=touch
55 | mode=777
56 | with_items:
57 | - settings.xml
58 |
59 | - name: set settings.xml aliyun
60 | blockinfile:
61 | path: "{{ maven_install_folder }}/apache-maven-3.6.3/conf/settings.xml"
62 | marker: ""
63 | block: |
64 |
65 |
68 |
69 |
70 | /opt/local_maven_repository
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | aliyun
84 |
85 |
86 | aliyun
87 | http://maven.aliyun.com/nexus/content/groups/public/
88 |
89 | true
90 |
91 |
92 | true
93 |
94 |
95 |
96 |
97 |
98 | aliyun
99 | http://maven.aliyun.com/nexus/content/groups/public/
100 |
101 | true
102 |
103 |
104 | true
105 |
106 |
107 |
108 |
109 |
110 | maven
111 |
112 |
113 | maven
114 | https://repo.maven.apache.org/maven2/
115 |
116 | true
117 |
118 |
119 | true
120 |
121 |
122 |
123 |
124 |
125 | maven
126 | https://repo.maven.apache.org/maven2/
127 |
128 | true
129 |
130 |
131 | true
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | aliyun
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/share-file/playbook/7-nginx-playbook.yml:
--------------------------------------------------------------------------------
1 | - hosts: all
2 | remote_user: root
3 | tasks:
4 | - name: install nginx
5 | yum:
6 | name: nginx
7 |
8 | - name: create conf file
9 | file:
10 | path="/etc/nginx/conf.d/{{ item }}"
11 | state=touch
12 | mode=777
13 | with_items:
14 | - http-redirect-https.conf
15 | - api.conf
16 | - admin-front.conf
17 | - h5-web-front.conf
18 | - pc-web-front.conf
19 |
20 | - name: set http-redirect-https.conf
21 | blockinfile:
22 | path: /etc/nginx/conf.d/http-redirect-https.conf
23 | marker: ""
24 | block: |
25 | server {
26 | listen 80;
27 | server_name www.cdk8s.com cdk8s.com api.cdk8s.com;
28 | return 301 https://$server_name$request_uri;
29 | }
30 |
31 | - name: set api.conf
32 | blockinfile:
33 | path: /etc/nginx/conf.d/api.conf
34 | marker: ""
35 | block: |
36 | server {
37 | charset utf-8;
38 | client_max_body_size 128M;
39 |
40 | #listen 80;
41 | listen 443 ssl;
42 |
43 | ssl_certificate /opt/jar/ssl/server.crt;
44 | ssl_certificate_key /opt/jar/ssl/server.key;
45 |
46 | ssl_session_timeout 5m;
47 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
48 | ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
49 | ssl_prefer_server_ciphers on;
50 |
51 | server_name www.cdk8s.com cdk8s.com api.cdk8s.com;
52 |
53 | location ^~ /upload {
54 | root /home/jenkins/sculptor-boot-backend-upload-dir;
55 | autoindex on;
56 | autoindex_exact_size off;
57 | autoindex_localtime on;
58 | }
59 |
60 | location ^~ /sculptor-boot-backend/ {
61 | proxy_pass http://127.0.0.1:9091;
62 | proxy_redirect off;
63 | proxy_set_header Host $host;
64 | proxy_set_header X-Real-IP $remote_addr;
65 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
66 | proxy_set_header X-Forwarded-Proto $scheme;
67 | }
68 |
69 | location ^~ /logs {
70 | root /home/jenkins/workspace/sculptor-boot-backend;
71 | autoindex on;
72 | autoindex_exact_size off;
73 | autoindex_localtime on;
74 | }
75 | }
76 |
77 | - name: set admin-front.conf
78 | blockinfile:
79 | path: /etc/nginx/conf.d/admin-front.conf
80 | marker: ""
81 | block: |
82 | server {
83 | charset utf-8;
84 | client_max_body_size 128M;
85 |
86 | #listen 80;
87 | listen 443 ssl;
88 |
89 | ssl_certificate /opt/jar/ssl/server.crt;
90 | ssl_certificate_key /opt/jar/ssl/server.key;
91 |
92 | ssl_session_timeout 5m;
93 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
94 | ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
95 | ssl_prefer_server_ciphers on;
96 |
97 | server_name admin-front.cdk8s.com;
98 |
99 | location ^~ /rcxt-react {
100 | root /home/jenkins/workspace/rcxt-react;
101 | index index.html;
102 | try_files $uri /rcxt-react/index.html;
103 | }
104 | }
105 |
106 | - name: set h5-web-front.conf
107 | blockinfile:
108 | path: /etc/nginx/conf.d/h5-web-front.conf
109 | marker: ""
110 | block: |
111 | server {
112 | charset utf-8;
113 | client_max_body_size 128M;
114 |
115 | #listen 80;
116 | listen 443 ssl;
117 |
118 | ssl_certificate /opt/jar/ssl/server.crt;
119 | ssl_certificate_key /opt/jar/ssl/server.key;
120 |
121 | ssl_session_timeout 5m;
122 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
123 | ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
124 | ssl_prefer_server_ciphers on;
125 |
126 | server_name h5.cdk8s.com;
127 |
128 | location / {
129 | root /home/jenkins/workspace/rcxt-web-online;
130 | index index.html index.htm;
131 | }
132 | }
133 |
134 | - name: set pc-web-front.conf
135 | blockinfile:
136 | path: /etc/nginx/conf.d/pc-web-front.conf
137 | marker: ""
138 | block: |
139 | server {
140 | charset utf-8;
141 | client_max_body_size 128M;
142 |
143 | #listen 80;
144 | listen 443 ssl;
145 |
146 | ssl_certificate /opt/jar/ssl/server.crt;
147 | ssl_certificate_key /opt/jar/ssl/server.key;
148 |
149 | ssl_session_timeout 5m;
150 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
151 | ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
152 | ssl_prefer_server_ciphers on;
153 |
154 | server_name www.cdk8s.com;
155 |
156 | location / {
157 | root /home/jenkins/workspace/rcxt-web;
158 | index index.html index.htm;
159 | }
160 | }
161 |
162 | - name: insert gzip config
163 | blockinfile:
164 | path: /etc/nginx/nginx.conf
165 | marker: " "
166 | insertafter: "^http {"
167 | block: |
168 | gzip on;
169 | gzip_buffers 8 16k;
170 | gzip_min_length 512;
171 | gzip_disable "MSIE [1-6]\.(?!.*SV1)";
172 | gzip_http_version 1.1;
173 | gzip_types text/plain text/css application/javascript application/x-javascript application/json application/xml;
174 |
175 | - name: enable nginx
176 | shell: "{{ item }}"
177 | with_items:
178 | - systemctl enable nginx
179 | - systemctl restart nginx
180 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ## Git
3 |
4 | - Github:
5 | - Gitee:
6 | - Gitbook:
7 |
8 | ## Hosts
9 |
10 | ```
11 | 127.0.0.1 sso.cdk8s.com
12 | 127.0.0.1 test1.cdk8s.com
13 | 127.0.0.1 test2.cdk8s.com
14 | 127.0.0.1 redis.cdk8s.com
15 | 127.0.0.1 mysql.cdk8s.com
16 | 127.0.0.1 management.cdk8s.com
17 | 127.0.0.1 management-frontend.cdk8s.com
18 | ```
19 |
20 | ## Architecture
21 |
22 | 
23 |
24 | - 上图的视频讲解:[B 站](https://www.bilibili.com/video/av65883281/)、[腾讯视频](https://v.qq.com/x/page/e0920wdqe7v.html)
25 | - OAuth2.0 授权码模式细节时序图可以查看:[点击我查看](http://img.gitnavi.com/tkey/tkey-oauth.png)
26 |
27 | ## Documentation
28 |
29 | - 我们统一了 TKey 项目的所有文档,方便大家查看
30 | - Github:
31 | - Gitee:
32 | - Gitbook:
33 | - **认识阶段 (必读)**
34 | - 单点登录系统认知与基础介绍:[Github](https://github.com/cdk8s/tkey-docs/blob/master/other/tkey-baisc.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/other/tkey-baisc.md)
35 | - 故意设计点(常见问题):[Github](https://github.com/cdk8s/tkey-docs/blob/master/faq/README.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/faq/README.md)
36 | - 项目结构与端口占用:[Github](https://github.com/cdk8s/tkey-docs/blob/master/other/project-structure.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/other/project-structure.md)
37 | - OAuth2.0 四种模式:[Github](https://github.com/cdk8s/tkey-docs/blob/master/server/oauth-grant-type/README.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/server/oauth-grant-type/README.md)
38 | - JAR 方式部署:[Github](https://github.com/cdk8s/tkey-docs/blob/master/deployment/jar-runapp.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/deployment/jar-runapp.md)
39 | - Docker 方式部署:[Github](https://github.com/cdk8s/tkey-docs/blob/master/deployment/docker-runapp.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/deployment/docker-runapp.md)
40 | - Docker Compose 方式部署:[Github](https://github.com/cdk8s/tkey-docs/blob/master/deployment/docker-compose-runapp.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/deployment/docker-compose-runapp.md)
41 | - TKey Server 开发阶段
42 | - 开发改造引导:[Github](https://github.com/cdk8s/tkey-docs/blob/master/server/dev.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/server/dev.md)
43 | - TKey Management 开发阶段(也是前后端分离的最佳实践示例)
44 | - 后端开发改造引导:[Github](https://github.com/cdk8s/tkey-docs/blob/master/management/dev-backend.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/management/dev-backend.md)
45 | - 前端开发改造引导:[Github](https://github.com/cdk8s/tkey-docs/blob/master/management/dev-frontend.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/management/dev-frontend.md)
46 | - TKey Client Java 开发阶段
47 | - 自己封装的 REST Client:[Github](https://github.com/cdk8s/tkey-docs/blob/master/client/dev-rest-client.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/client/dev-rest-client.md)
48 | - Spring Security 支持:[Github](https://github.com/cdk8s/tkey-docs/blob/master/client/dev-spring-security-client.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/client/dev-spring-security-client.md)
49 | - 测试阶段
50 | - 单元测试:[Github](https://github.com/cdk8s/tkey/blob/master/src/test/java/com/cdk8s/tkey/server/controller/AuthorizationCodeByFormTest.java)、[Gitee](https://gitee.com/cdk8s/tkey/blob/master/src/test/java/com/cdk8s/tkey/server/controller/AuthorizationCodeByFormTest.java)
51 | - 压力测试:[Github](https://github.com/cdk8s/tkey-docs/blob/master/test/performance.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/test/performance.md)
52 | - 部署阶段
53 | - 生产注意事项:[Github](https://github.com/cdk8s/tkey-docs/blob/master/deployment/production-environment.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/deployment/production-environment.md)
54 | - 部署环境搭建:[Github](https://github.com/cdk8s/tkey-docs/blob/master/deployment/deployment-core.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/deployment/deployment-core.md)
55 | - 监控阶段
56 | - Spring Boot Micrometer:[Github](https://github.com/cdk8s/tkey-docs/blob/master/deployment/micrometer.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/deployment/micrometer.md)
57 | - 其他工具全在 `部署环境搭建`,请自行查看
58 | - 线上问题诊断
59 | - [Actuator 在线修改 log 输出级别(Gif 动图)](http://img.gitnavi.com/tkey/actuator-update-log-level.gif)
60 | - [Arthas 诊断 Docker 应用](https://alibaba.github.io/arthas/docker.html#dockerjava)
61 | - 夜间开放端口,挑选流量远程 Debug:[Github](https://github.com/cdk8s/tkey-docs/blob/master/server/remote-debug.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/server/remote-debug.md)
62 |
63 |
64 | ## TKey Client
65 |
66 | - Java 前后端分离最佳实践
67 | - TKey SSO Client Management Backend:[Github](https://github.com/cdk8s/tkey-management)、[Gitee](https://gitee.com/cdk8s/tkey-management)
68 | - TKey SSO Client Management Frontend:[Github](https://github.com/cdk8s/tkey-management-frontend)、[Gitee](https://gitee.com/cdk8s/tkey-management)
69 | - Angular、Vue 的前后端分离版本会在稍后几周发出来
70 | - Java REST API 客户端:[Github](https://github.com/cdk8s/tkey-client-java)、[Gitee](https://gitee.com/cdk8s/tkey-client-java)
71 | - Java Spring Security 客户端:[Github](https://github.com/cdk8s/tkey-client-java-spring-security)、[Gitee](https://gitee.com/cdk8s/tkey-client-java-spring-security)
72 | - C#(暂缺)
73 | - GO(暂缺)
74 | - PHP(暂缺)
75 | - Python(暂缺)
76 | - Ruby(暂缺)
77 | - Node.js(暂缺)
78 |
79 | ## Share
80 |
81 | - Grafana Dashboard:[Github](https://github.com/cdk8s/tkey-docs/blob/master/share-file/grafana/dashboard.json)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/share-file/grafana/dashboard.json)
82 | - Postman API:[Github](https://github.com/cdk8s/tkey-docs/blob/master/share-file/postman/tkey-sso-server-api_collection_2.1_format.json)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/share-file/postman/tkey-sso-server-api_collection_2.1_format.json)
83 | - Run JAR Shell:[Github](https://github.com/cdk8s/tkey-docs/blob/master/share-file/shell/runapp.sh)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/share-file/shell/runapp.sh)
84 |
85 |
86 | ## Roadmap
87 |
88 | - 规划版本:[Github](https://github.com/cdk8s/tkey-docs/blob/master/roadmap/README.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/roadmap/README.md)
89 |
90 | ## Changelog
91 |
92 | - 版本更新:[Github](https://github.com/cdk8s/tkey-docs/blob/master/changelog/README.md)、[Gitee](https://gitee.com/cdk8s/tkey-docs/blob/master/changelog/README.md)
93 |
94 |
95 | ## Issues
96 |
97 | - 目前只开放了一个 issues 入口,集中问题,可以方便大家检索。
98 | - 去提问:[Github](https://github.com/cdk8s/tkey-issues)、[Gitee](https://gitee.com/cdk8s/tkey-issues)
99 |
100 | ## Contributors
101 |
102 | - 暂无
103 | - 欢迎 pull request
104 |
105 | ## Adopters
106 |
107 | - 去申请:[Github](https://github.com/cdk8s/tkey-issues/issues/1)、[Gitee](https://gitee.com/cdk8s/tkey-issues/issues/1)
108 |
109 | ## Sponsors
110 |
111 | - 暂无
112 |
113 | ## Backer
114 |
115 | - [我要喝喜茶 Orz..](http://www.youmeek.com/donate/)
116 |
117 |
118 | ## Join
119 |
120 | - 邮箱:`cdk8s#qq.com`
121 | - 博客:
122 | - Github:
123 | - Gitee:
124 | - 公众号
125 |
126 | 
127 |
128 |
129 | ## Jobs
130 |
131 | - 我们在广州
132 | - 有广州或深圳的合作、Offer 欢迎联系我们
133 | - 邮箱:`cdk8s#qq.com`
134 | - 公众号:`联系我们`
135 |
136 | ## Thanks
137 |
138 | - [IntelliJ IDEA](https://www.jetbrains.com/idea/)
139 | - [CAS](https://github.com/apereo/cas)
140 | - [Okta](https://www.okta.com/)
141 |
142 |
143 | ## Copyright And License
144 |
145 | - Copyright (c) CDK8S. All rights reserved.
146 | - Licensed under the **MIT** license.
147 | - **再次强调: 因为是 MIT 协议,大家有不满意的,除了 PR 也可以 fork 后自己尽情改造!**
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/other/tkey-baisc.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## 个人认知
4 |
5 | - 在稍微大一点点的公司中,有两个基础系统是必然有的:一个是:SSO(单点登录系统),一个是 UPMS(通用用户权限管理系统)
6 | - 而这两个系统都是很难完全地直接套用开源框架。因为,在这类规模公司中,基本已经有成气候的系统、用户,这部分用户体系,不可能说换就换。一般是要反过来设置:让新系统去适应现有的账号系统、权限管理体系。
7 | - 目前单点登录技术选型中,用得比较多的有:CAS、Keycloak、Spring Security OAuth2
8 | - 其中 Keycloak 除了认证还带各种授权玩法,整个体系的规划挺好的,适合业务的一开始阶段。如果是成规模之后再考虑要使用它,改造成本很大。
9 | - CAS 什么都好,支持了各种扩展接口,几百个可扩展的子模块。但是,这么大的项目现在就一个人维护,他既要开发又要写文档、写测试,实在是难为他了。记忆深刻 2017 年他嫌提问的人太 low、太麻烦,直接把 issues 关了,至今未开。而且这家伙非常喜欢用新版本,JDK、Spring Boot 动不动就升级。现在想起研究它的那段时间,简直了...Orz
10 | - Spring Security OAuth2 是 Spring Cloud 流行之后大家非常喜欢用的一个系统。目前来说真的没啥缺点,不管是可读性、可维护性、可变更性等方面上,大家都很喜欢。但是,不够灵活,业务上的灵活,特别是国内各种非工程化思维下的各种特殊要求。我不觉得老板们这些需求不合理,但是基于这些开源系统真的好难。
11 | - 所以,我写了 TKey,目标很明确:需求总是各种各样,我没办法帮大家做好扩展,那我就帮大家写好文档。你们自己知道怎么用,自己爱怎么改就怎么改。
12 |
13 |
14 | ## OAuth 核心(比较绕)
15 |
16 | - TKey 的接口是按照 OAuth 2.0 规范来,所以必须了解这个。
17 | - OAuth 2.0 是规范、是安全标准,不是框架。它的核心逻辑是:颁发 Token,使用 Token
18 | - OAuth 2.0 规范定义了授权协议,不是身份认证协议
19 | - OAuth 2.0 广泛用于各大开放平台,比如大家常接触的 QQ、微信等平台
20 | - 认证系统可以支持很多协议,比如 SAML、LDAP 等,OAuth 2.0 可以只是其中的一种。
21 | - 单单的 OAuth 2.0 协议是做不了一个认证系统
22 | - OpenID Connect 开放协议是建立在 OAuth 2.0 之上的,它就可以作为认证协议
23 | - 除了 OpenID Connect,基于 OAuth 2.0 构建的协议还有很多,UMA、HEART、iGov 等
24 | - TKey 作为认证系统的认证核心是:
25 | - 用户持有的 TGC 令牌(ID 令牌),它才是代表着用户信息,代表着认证系统的登录证明。用户与登录系统之间是用 TGC 来连接。TGC 生成方法:`oauthGenerateService.generateTgc();`
26 | - OAuth 所颁发的 Token 是让客户端系统(业务系统)与认证系统之间进行连接
27 | - TKey 基于 OAuth 2.0 进行设计的的最大好处在于它是通用标准,在让别人来对接我们登录系统的时候只要按照标准即可
28 | - 所以,可以把接入 TKey 过程理解成接入 QQ 开放平台、微信开放平台过程
29 | - 授权码模式时序图
30 |
31 | 
32 |
33 |
34 | -------------------------------------------------------------------
35 |
36 |
37 | ## 常见登录系统
38 |
39 | - 最优秀登录系统:Google Accounts
40 | - 在 Google 那么多产品中,登录这件事是那么的经典而自然,永远的地方都是:
41 | - 较一般的:腾讯、阿里等
42 | - 阿里的淘宝和天猫是同一个用户体系,阿里云是另外一个体系。
43 | - 腾讯的 QQ 和微信各自独立
44 | - 百度普通用户和百度智能云用户也是两个用户体系
45 | - 类似 Okta 这类新玩法,当前国内 saas 丰富度还不够,暂时比较艰难
46 |
47 | ## 登录系统的几种场景
48 |
49 | - **最核心的点:** 对于业务系统来讲,有没有前置的 API 网关影响一生
50 | - **API 网关作用:** 路由、过滤、身份验证、鉴权、限流、熔断、重试、监控、负载、版本/灰度发布、缓存等等
51 | - API 网关是所有请求的第一道入口,如果你们公司刚好再做整体系统架构调整,要引入单点登录系统之前,我建议一同连同 API 网关一起调研了
52 |
53 | ## 开放平台的登录系统
54 |
55 | - 类似 QQ 第三方登录过程
56 | - 你需要找 QQ 开放平台先申请 AppId + AppKey
57 | - 也有人叫做:AppKey + AppSecret; ClientId + ClientSecret
58 | - OAuth 2.0 规范的标准叫法是:ClientId + ClientSecret,[具体点击查看](https://tools.ietf.org/html/rfc6749#section-11.2.2)
59 | - 采用授权码模式拿到 QQ 平台给你的 AccessToken
60 | - 这个 AccessToken 你只能获取到用户基本信息
61 | - 在你调用 QQ 平台的所有接口过程中,必须带上该 AccessToken,不然它不知道是谁在调用
62 | - 你只能跟 QQ 开放平台打交道,你不能拿着这个 AccessToken 去调用微信开放平台
63 |
64 |
65 | ## 有 API 网关的同构业务系统
66 |
67 | - 比如 Spring 的 Spring Cloud 体系
68 | - 对身份进行认证全部交给 Gateway、Zuul,内部的业务系统只要管理好自己的 API 服务即可
69 | - 在 Spring Cloud 体系中,内部的服务都是在内网中,都是设定彼此之间是安全的
70 |
71 |
72 | ## 有 API 网关的异构业务系统
73 |
74 | - 有的公司有好几个研发中心、研发部门,各自采用各自的业务系统架构(历史原因)
75 | - 引入 Kong、Tyk、OpenResty + Lua 等 API 网关之后,各个业务系统在网关后面,身份验证也是交给网关
76 |
77 |
78 | ## 无 API 网关的同构 / 异构系统
79 |
80 | - **这种场景在中型公司转型过程中基本都要遇到,我个人建议是 API 网关和单点登录一起抓**
81 | - 这里说下在有单点登录系统情况下,但没有 API 网关的跨系统调用
82 | - 业务系统 A 在单点登录系统登录成功后拿到属于自己的 Token-A
83 | - 当同一个浏览器访问业务系统 B 的时候,B 系统也是需要登录的,但是因为单点登录系统已经知道当前浏览器是谁在用,所以直接给业务系统 B 颁发了 Token-B。这个过程用户无需重新登录,也就单点登录了
84 | - 业务系统 A 自己维 Session-A 与 Token-A 之间的关系
85 | - 业务系统 B 自己维 Session-B 与 Token-B 之间的关系
86 | - 这时候业务系统 A 要调用业务系统 B,必须拿着 Token-A 去找业务系统 B
87 | - 业务系统 B 拿到请求中的 Token-A 会找单点系统询问该 Token-A 是否有效,以及 Token-A 对应用户信息是谁
88 | - 业务系统 B 知道当前请求是谁之后就会放开请求
89 | - 这个过程是一个瓶颈
90 | - 如果业务系统 B 自己不存储这些 Token-A,则每次都要询问单点登录系统,单点登录系统压力会很大
91 | - 如果业务系统 B 自己存储这些 Token-A,则 Token-A 的时效性就有偏差
92 |
93 |
94 | ## OAuth 2.0 与 JWT
95 |
96 | - 现在有很多人喜欢用 Spring Security OAuth + JWT 构建登录系统
97 | - JWT 的自包含、防篡改的特点让很多人喜欢,可以省掉最让人烦的集中式的令牌,实现无状态。
98 | - 可是,这是有场景限制的。比如主动吊销 Token 要如何处理、有效时长如何动态控制、密钥如何动态切换。
99 | - 如果没有主动吊销 Token 的业务需求,那自包含的特点确实很有用,只是看大家的业务场景了。
100 |
101 |
102 |
103 | -------------------------------------------------------------------
104 |
105 | ## 其他核心术语认知(提供了查询入口)
106 |
107 | > 架构设计 无状态
108 |
109 | - [Google 搜索](https://www.google.com/search?q=%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1%20%E6%97%A0%E7%8A%B6%E6%80%81)
110 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1%20%E6%97%A0%E7%8A%B6%E6%80%81)
111 |
112 | > 认证 与 授权 的区别
113 |
114 | - [Google 搜索](https://www.google.com/search?q=%E8%AE%A4%E8%AF%81%20%E4%B8%8E%20%E6%8E%88%E6%9D%83%20%E7%9A%84%E5%8C%BA%E5%88%AB)
115 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=%E8%AE%A4%E8%AF%81%20%E4%B8%8E%20%E6%8E%88%E6%9D%83%20%E7%9A%84%E5%8C%BA%E5%88%AB)
116 |
117 | > HTTP 请求头:User-Agent
118 |
119 | - [Google 搜索](https://www.google.com/search?q=HTTP%20%E8%AF%B7%E6%B1%82%E5%A4%B4%EF%BC%9AUser-Agent)
120 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=HTTP%20%E8%AF%B7%E6%B1%82%E5%A4%B4%EF%BC%9AUser-Agent)
121 |
122 | > HTTP 状态码:301 302 401 403
123 |
124 | - [Google 搜索](https://www.google.com/search?q=HTTP%20%E7%8A%B6%E6%80%81%E7%A0%81%EF%BC%9A301%20302%20401%20403)
125 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=HTTP%20%E7%8A%B6%E6%80%81%E7%A0%81%EF%BC%9A301%20302%20401%20403)
126 |
127 | > 跨域
128 |
129 | - [Google 搜索](https://www.google.com/search?q=%E8%B7%A8%E5%9F%9F)
130 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=%E8%B7%A8%E5%9F%9F)
131 |
132 | > 分布式 无状态
133 |
134 | - [Google 搜索](https://www.google.com/search?q=%E5%88%86%E5%B8%83%E5%BC%8F%20%E6%97%A0%E7%8A%B6%E6%80%81)
135 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=%E5%88%86%E5%B8%83%E5%BC%8F%20%E6%97%A0%E7%8A%B6%E6%80%81)
136 |
137 | > 中间人攻击
138 |
139 | - [Google 搜索](https://www.google.com/search?q=%E4%B8%AD%E9%97%B4%E4%BA%BA%E6%94%BB%E5%87%BB)
140 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=%E4%B8%AD%E9%97%B4%E4%BA%BA%E6%94%BB%E5%87%BB)
141 |
142 | > 重放攻击
143 |
144 | - [Google 搜索](https://www.google.com/search?q=%E9%87%8D%E6%94%BE%E6%94%BB%E5%87%BB)
145 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=%E9%87%8D%E6%94%BE%E6%94%BB%E5%87%BB)
146 |
147 | > Session 与 Cookie
148 |
149 | - [Google 搜索](https://www.google.com/search?q=Session%20%E4%B8%8E%20Cookie)
150 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=Session%20%E4%B8%8E%20Cookie)
151 |
152 | > Tomcat JSESSIONID 作用
153 |
154 | - [Google 搜索](https://www.google.com/search?q=Tomcat%20JSESSIONID%20%E4%BD%9C%E7%94%A8)
155 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=Tomcat%20JSESSIONID%20%E4%BD%9C%E7%94%A8)
156 |
157 | > Cookie HttpOnly secure
158 |
159 | - [Google 搜索](https://www.google.com/search?q=Cookie%20HttpOnly%20secure)
160 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=Cookie%20HttpOnly%20secure)
161 |
162 | > LocalStorage 与 SessionStorage
163 |
164 | - [Google 搜索](https://www.google.com/search?q=LocalStorage%20%E4%B8%8E%20SessionStorage)
165 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=LocalStorage%20%E4%B8%8E%20SessionStorage)
166 |
167 | > Basic Auth Bearer Token
168 |
169 | - [Google 搜索](https://www.google.com/search?q=Basic%20Auth%20Bearer%20Token)
170 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=Basic%20Auth%20Bearer%20Token)
171 |
172 | > OAuth 2.0 四种授权模式
173 |
174 | - [Google 搜索](https://www.google.com/search?q=OAuth%202.0%20%E5%9B%9B%E7%A7%8D%E6%8E%88%E6%9D%83%E6%A8%A1%E5%BC%8F)
175 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=OAuth%202.0%20%E5%9B%9B%E7%A7%8D%E6%8E%88%E6%9D%83%E6%A8%A1%E5%BC%8F)
176 | - 授权码模式把步骤拆开,最核心的点:保证了是客户端本身进行的身份认证。简化模式就做不到,所以不推荐简化模式。
177 |
178 | > OAuth 2.0 state CSRF
179 |
180 | - [Google 搜索](https://www.google.com/search?q=OAuth%202.0%20state%20CSRF)
181 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=OAuth%202.0%20state%20CSRF)
182 |
183 | > OAuth 2.0 redirect_uri 验证
184 |
185 | - [Google 搜索](https://www.google.com/search?q=OAuth%202.0%20redirect_uri%20%E9%AA%8C%E8%AF%81)
186 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=OAuth%202.0%20redirect_uri%20%E9%AA%8C%E8%AF%81)
187 |
188 | > API 网关的作用
189 |
190 | - [Google 搜索](https://www.google.com/search?q=API%20%E7%BD%91%E5%85%B3%E7%9A%84%E4%BD%9C%E7%94%A8)
191 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=API%20%E7%BD%91%E5%85%B3%E7%9A%84%E4%BD%9C%E7%94%A8)
192 |
193 | > UPMS 用户权限管理系统
194 |
195 | - [Google 搜索](https://www.google.com/search?q=UPMS%20%E7%94%A8%E6%88%B7%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F)
196 | - [Baidu 搜索](https://www.baidu.com/baidu?wd=UPMS%20%E7%94%A8%E6%88%B7%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F)
197 |
198 |
199 |
200 |
--------------------------------------------------------------------------------
/share-file/postman/tkey-sso-server-api_collection_2.1_format.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "_postman_id": "be664928-7ed2-41c3-994e-da8b4adde66a",
4 | "name": "tkey-sso-server-api",
5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
6 | },
7 | "item": [
8 | {
9 | "name": "tkey-sso-client-rest-demo",
10 | "item": [
11 | {
12 | "name": "通用",
13 | "item": [
14 | {
15 | "name": "刷新token",
16 | "request": {
17 | "method": "POST",
18 | "header": [
19 | {
20 | "key": "Content-Type",
21 | "value": "application/x-www-form-urlencoded"
22 | }
23 | ],
24 | "body": {
25 | "mode": "urlencoded",
26 | "urlencoded": [
27 | {
28 | "key": "grant_type",
29 | "value": "refresh_token",
30 | "type": "text"
31 | },
32 | {
33 | "key": "refresh_token",
34 | "value": "RT-103-8aI3zHbArcmzT3ukHlBQ88AdMv2NB8Aa",
35 | "type": "text"
36 | },
37 | {
38 | "key": "client_id",
39 | "value": "test_client_id_1",
40 | "type": "text"
41 | },
42 | {
43 | "key": "client_secret",
44 | "value": "test_client_secret_1",
45 | "type": "text"
46 | }
47 | ]
48 | },
49 | "url": {
50 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/token",
51 | "protocol": "http",
52 | "host": [
53 | "sso",
54 | "cdk8s",
55 | "com"
56 | ],
57 | "port": "9091",
58 | "path": [
59 | "sso",
60 | "oauth",
61 | "token"
62 | ]
63 | }
64 | },
65 | "response": []
66 | },
67 | {
68 | "name": "校验 AccessToken",
69 | "request": {
70 | "method": "POST",
71 | "header": [
72 | {
73 | "key": "Content-Type",
74 | "value": "application/x-www-form-urlencoded"
75 | }
76 | ],
77 | "body": {
78 | "mode": "urlencoded",
79 | "urlencoded": [
80 | {
81 | "key": "client_id",
82 | "value": "test_client_id_1",
83 | "type": "text"
84 | },
85 | {
86 | "key": "client_secret",
87 | "value": "test_client_secret_1",
88 | "type": "text"
89 | },
90 | {
91 | "key": "token",
92 | "value": "AT-102-dJTLEsFLR2PbxU1l8GPx3CUS9O3Lhzdn",
93 | "type": "text"
94 | },
95 | {
96 | "key": "token_type_hint",
97 | "value": "access_token",
98 | "type": "text"
99 | }
100 | ]
101 | },
102 | "url": {
103 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/introspect",
104 | "protocol": "http",
105 | "host": [
106 | "sso",
107 | "cdk8s",
108 | "com"
109 | ],
110 | "port": "9091",
111 | "path": [
112 | "sso",
113 | "oauth",
114 | "introspect"
115 | ]
116 | }
117 | },
118 | "response": []
119 | },
120 | {
121 | "name": "校验 RefreshToken",
122 | "request": {
123 | "method": "POST",
124 | "header": [
125 | {
126 | "key": "Content-Type",
127 | "value": "application/x-www-form-urlencoded"
128 | }
129 | ],
130 | "body": {
131 | "mode": "urlencoded",
132 | "urlencoded": [
133 | {
134 | "key": "client_id",
135 | "value": "test_client_id_1",
136 | "type": "text"
137 | },
138 | {
139 | "key": "client_secret",
140 | "value": "test_client_secret_1",
141 | "type": "text"
142 | },
143 | {
144 | "key": "token",
145 | "value": "RT-103-8aI3zHbArcmzT3ukHlBQ88AdMv2NB8Aa",
146 | "type": "text"
147 | },
148 | {
149 | "key": "token_type_hint",
150 | "value": "refresh_token",
151 | "type": "text"
152 | }
153 | ]
154 | },
155 | "url": {
156 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/introspect",
157 | "protocol": "http",
158 | "host": [
159 | "sso",
160 | "cdk8s",
161 | "com"
162 | ],
163 | "port": "9091",
164 | "path": [
165 | "sso",
166 | "oauth",
167 | "introspect"
168 | ]
169 | }
170 | },
171 | "response": []
172 | },
173 | {
174 | "name": "获取用户信息-POST",
175 | "request": {
176 | "method": "POST",
177 | "header": [
178 | {
179 | "key": "Content-Type",
180 | "value": "application/x-www-form-urlencoded"
181 | }
182 | ],
183 | "body": {
184 | "mode": "urlencoded",
185 | "urlencoded": [
186 | {
187 | "key": "access_token",
188 | "value": "RT-103-8aI3zHbArcmzT3ukHlBQ88AdMv2NB8Aa",
189 | "type": "text"
190 | }
191 | ]
192 | },
193 | "url": {
194 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/userinfo",
195 | "protocol": "http",
196 | "host": [
197 | "sso",
198 | "cdk8s",
199 | "com"
200 | ],
201 | "port": "9091",
202 | "path": [
203 | "sso",
204 | "oauth",
205 | "userinfo"
206 | ]
207 | }
208 | },
209 | "response": []
210 | },
211 | {
212 | "name": "获取用户信息-GET",
213 | "request": {
214 | "method": "GET",
215 | "header": [],
216 | "url": {
217 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/userinfo?access_token=AT-102-dJTLEsFLR2PbxU1l8GPx3CUS9O3Lhzdn",
218 | "protocol": "http",
219 | "host": [
220 | "sso",
221 | "cdk8s",
222 | "com"
223 | ],
224 | "port": "9091",
225 | "path": [
226 | "sso",
227 | "oauth",
228 | "userinfo"
229 | ],
230 | "query": [
231 | {
232 | "key": "access_token",
233 | "value": "AT-102-dJTLEsFLR2PbxU1l8GPx3CUS9O3Lhzdn"
234 | }
235 | ]
236 | }
237 | },
238 | "response": []
239 | },
240 | {
241 | "name": "登出",
242 | "request": {
243 | "method": "GET",
244 | "header": [],
245 | "url": {
246 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/logout?redirect_uri=http://www.gitnavi.com",
247 | "protocol": "http",
248 | "host": [
249 | "sso",
250 | "cdk8s",
251 | "com"
252 | ],
253 | "port": "9091",
254 | "path": [
255 | "sso",
256 | "oauth",
257 | "logout"
258 | ],
259 | "query": [
260 | {
261 | "key": "redirect_uri",
262 | "value": "http://www.gitnavi.com"
263 | }
264 | ]
265 | }
266 | },
267 | "response": []
268 | }
269 | ],
270 | "event": [
271 | {
272 | "listen": "prerequest",
273 | "script": {
274 | "id": "0f576257-c509-4fba-8365-32522c551d70",
275 | "type": "text/javascript",
276 | "exec": [
277 | ""
278 | ]
279 | }
280 | },
281 | {
282 | "listen": "test",
283 | "script": {
284 | "id": "fb396949-c6f8-4969-8823-c3361694741a",
285 | "type": "text/javascript",
286 | "exec": [
287 | ""
288 | ]
289 | }
290 | }
291 | ],
292 | "_postman_isSubFolder": true
293 | },
294 | {
295 | "name": "简化模式",
296 | "item": [
297 | {
298 | "name": "1.简化模式(使用浏览器访问)",
299 | "request": {
300 | "method": "GET",
301 | "header": [],
302 | "url": {
303 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/authorize?response_type=token&client_id=test_client_id_1&redirect_uri=http://www.gitnavi.com",
304 | "protocol": "http",
305 | "host": [
306 | "sso",
307 | "cdk8s",
308 | "com"
309 | ],
310 | "port": "9091",
311 | "path": [
312 | "sso",
313 | "oauth",
314 | "authorize"
315 | ],
316 | "query": [
317 | {
318 | "key": "response_type",
319 | "value": "token"
320 | },
321 | {
322 | "key": "client_id",
323 | "value": "test_client_id_1"
324 | },
325 | {
326 | "key": "redirect_uri",
327 | "value": "http://www.gitnavi.com"
328 | }
329 | ]
330 | }
331 | },
332 | "response": []
333 | },
334 | {
335 | "name": "2.用户名、密码提交(用户触发的请求)",
336 | "request": {
337 | "method": "POST",
338 | "header": [
339 | {
340 | "key": "Content-Type",
341 | "value": "application/x-www-form-urlencoded"
342 | }
343 | ],
344 | "body": {
345 | "mode": "urlencoded",
346 | "urlencoded": [
347 | {
348 | "key": "username",
349 | "value": "myname",
350 | "type": "text"
351 | },
352 | {
353 | "key": "password",
354 | "value": "123456",
355 | "type": "text"
356 | }
357 | ]
358 | },
359 | "url": {
360 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/authorize?response_type=token&client_id=test_client_id_1&redirect_uri=http://www.baidu.com",
361 | "protocol": "http",
362 | "host": [
363 | "sso",
364 | "cdk8s",
365 | "com"
366 | ],
367 | "port": "9091",
368 | "path": [
369 | "sso",
370 | "oauth",
371 | "authorize"
372 | ],
373 | "query": [
374 | {
375 | "key": "response_type",
376 | "value": "token"
377 | },
378 | {
379 | "key": "client_id",
380 | "value": "test_client_id_1"
381 | },
382 | {
383 | "key": "redirect_uri",
384 | "value": "http://www.baidu.com"
385 | }
386 | ]
387 | }
388 | },
389 | "response": []
390 | }
391 | ],
392 | "_postman_isSubFolder": true
393 | },
394 | {
395 | "name": "密码模式",
396 | "item": [
397 | {
398 | "name": "密码模式",
399 | "request": {
400 | "method": "POST",
401 | "header": [
402 | {
403 | "key": "Content-Type",
404 | "name": "Content-Type",
405 | "value": "application/x-www-form-urlencoded",
406 | "type": "text"
407 | }
408 | ],
409 | "body": {
410 | "mode": "urlencoded",
411 | "urlencoded": [
412 | {
413 | "key": "grant_type",
414 | "value": "password",
415 | "type": "text"
416 | },
417 | {
418 | "key": "client_id",
419 | "value": "test_client_id_1",
420 | "type": "text"
421 | },
422 | {
423 | "key": "client_secret",
424 | "value": "test_client_secret_1",
425 | "type": "text"
426 | },
427 | {
428 | "key": "username",
429 | "value": "admin",
430 | "type": "text"
431 | },
432 | {
433 | "key": "password",
434 | "value": "123456",
435 | "type": "text"
436 | }
437 | ]
438 | },
439 | "url": {
440 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/token",
441 | "protocol": "http",
442 | "host": [
443 | "sso",
444 | "cdk8s",
445 | "com"
446 | ],
447 | "port": "9091",
448 | "path": [
449 | "sso",
450 | "oauth",
451 | "token"
452 | ]
453 | }
454 | },
455 | "response": []
456 | }
457 | ],
458 | "_postman_isSubFolder": true
459 | },
460 | {
461 | "name": "客户端模式",
462 | "item": [
463 | {
464 | "name": "客户端模式-GET",
465 | "request": {
466 | "method": "GET",
467 | "header": [],
468 | "url": {
469 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/token?grant_type=client_credentials&client_id=test_client_id_1&client_secret=test_client_secret_1",
470 | "protocol": "http",
471 | "host": [
472 | "sso",
473 | "cdk8s",
474 | "com"
475 | ],
476 | "port": "9091",
477 | "path": [
478 | "sso",
479 | "oauth",
480 | "token"
481 | ],
482 | "query": [
483 | {
484 | "key": "grant_type",
485 | "value": "client_credentials"
486 | },
487 | {
488 | "key": "client_id",
489 | "value": "test_client_id_1"
490 | },
491 | {
492 | "key": "client_secret",
493 | "value": "test_client_secret_1"
494 | }
495 | ]
496 | }
497 | },
498 | "response": []
499 | },
500 | {
501 | "name": "客户端模式-POST",
502 | "request": {
503 | "method": "POST",
504 | "header": [
505 | {
506 | "key": "Content-Type",
507 | "name": "Content-Type",
508 | "value": "application/x-www-form-urlencoded",
509 | "type": "text"
510 | }
511 | ],
512 | "body": {
513 | "mode": "urlencoded",
514 | "urlencoded": [
515 | {
516 | "key": "grant_type",
517 | "value": "client_credentials",
518 | "type": "text"
519 | },
520 | {
521 | "key": "client_id",
522 | "value": "test_client_id_1",
523 | "type": "text"
524 | },
525 | {
526 | "key": "client_secret",
527 | "value": "test_client_secret_1",
528 | "type": "text"
529 | }
530 | ]
531 | },
532 | "url": {
533 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/token",
534 | "protocol": "http",
535 | "host": [
536 | "sso",
537 | "cdk8s",
538 | "com"
539 | ],
540 | "port": "9091",
541 | "path": [
542 | "sso",
543 | "oauth",
544 | "token"
545 | ]
546 | }
547 | },
548 | "response": []
549 | }
550 | ],
551 | "_postman_isSubFolder": true
552 | },
553 | {
554 | "name": "授权码模式",
555 | "item": [
556 | {
557 | "name": "1.登录页面(使用浏览器访问)",
558 | "request": {
559 | "method": "GET",
560 | "header": [],
561 | "url": {
562 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/authorize?response_type=code&client_id=test_client_id_1&redirect_uri=http://test1.cdk8s.com:9094/client-rest/codeCallback/aHR0cDovL3Rlc3QxLmNkazhzLmNvbTo5MzkzL2NsaWVudC1zY3JpYmVqYXZhL3VzZXI_aWQ9MTIzNDU2Jm5hbWU9Y2RrOHM",
563 | "protocol": "http",
564 | "host": [
565 | "sso",
566 | "cdk8s",
567 | "com"
568 | ],
569 | "port": "9091",
570 | "path": [
571 | "sso",
572 | "oauth",
573 | "authorize"
574 | ],
575 | "query": [
576 | {
577 | "key": "response_type",
578 | "value": "code"
579 | },
580 | {
581 | "key": "client_id",
582 | "value": "test_client_id_1"
583 | },
584 | {
585 | "key": "redirect_uri",
586 | "value": "http://test1.cdk8s.com:9094/client-rest/codeCallback/aHR0cDovL3Rlc3QxLmNkazhzLmNvbTo5MzkzL2NsaWVudC1zY3JpYmVqYXZhL3VzZXI_aWQ9MTIzNDU2Jm5hbWU9Y2RrOHM"
587 | }
588 | ]
589 | }
590 | },
591 | "response": []
592 | },
593 | {
594 | "name": "2.用户名、密码提交(用户触发的请求)",
595 | "request": {
596 | "method": "POST",
597 | "header": [
598 | {
599 | "key": "Content-Type",
600 | "value": "application/x-www-form-urlencoded"
601 | }
602 | ],
603 | "body": {
604 | "mode": "urlencoded",
605 | "urlencoded": [
606 | {
607 | "key": "username",
608 | "value": "myname",
609 | "type": "text"
610 | },
611 | {
612 | "key": "password",
613 | "value": "123456",
614 | "type": "text"
615 | }
616 | ]
617 | },
618 | "url": {
619 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/authorize?response_type=code&client_id=test_client_id_1&redirect_uri=http://test1.cdk8s.com:9094/client-rest/codeCallback/aHR0cDovL3Rlc3QxLmNkazhzLmNvbTo5MzkzL2NsaWVudC1zY3JpYmVqYXZhL3VzZXI_aWQ9MTIzNDU2Jm5hbWU9Y2RrOHM",
620 | "protocol": "http",
621 | "host": [
622 | "sso",
623 | "cdk8s",
624 | "com"
625 | ],
626 | "port": "9091",
627 | "path": [
628 | "sso",
629 | "oauth",
630 | "authorize"
631 | ],
632 | "query": [
633 | {
634 | "key": "response_type",
635 | "value": "code"
636 | },
637 | {
638 | "key": "client_id",
639 | "value": "test_client_id_1"
640 | },
641 | {
642 | "key": "redirect_uri",
643 | "value": "http://test1.cdk8s.com:9094/client-rest/codeCallback/aHR0cDovL3Rlc3QxLmNkazhzLmNvbTo5MzkzL2NsaWVudC1zY3JpYmVqYXZhL3VzZXI_aWQ9MTIzNDU2Jm5hbWU9Y2RrOHM"
644 | }
645 | ]
646 | }
647 | },
648 | "response": []
649 | },
650 | {
651 | "name": "3.code 换取 token",
652 | "request": {
653 | "method": "POST",
654 | "header": [
655 | {
656 | "key": "Content-Type",
657 | "value": "application/x-www-form-urlencoded"
658 | }
659 | ],
660 | "body": {
661 | "mode": "urlencoded",
662 | "urlencoded": [
663 | {
664 | "key": "grant_type",
665 | "value": "authorization_code",
666 | "type": "text"
667 | },
668 | {
669 | "key": "code",
670 | "value": "OC-101-b2XiPTubgiOkyNYlM9n48XvoVIY9BxtF",
671 | "type": "text"
672 | },
673 | {
674 | "key": "redirect_uri",
675 | "value": "http://test1.cdk8s.com:9094/client-rest/codeCallback/aHR0cDovL3Rlc3QxLmNkazhzLmNvbTo5MzkzL2NsaWVudC1zY3JpYmVqYXZhL3VzZXI_aWQ9MTIzNDU2Jm5hbWU9Y2RrOHM",
676 | "type": "text"
677 | },
678 | {
679 | "key": "client_id",
680 | "value": "test_client_id_1",
681 | "type": "text"
682 | },
683 | {
684 | "key": "client_secret",
685 | "value": "test_client_secret_1",
686 | "type": "text"
687 | }
688 | ]
689 | },
690 | "url": {
691 | "raw": "http://sso.cdk8s.com:9091/sso/oauth/token",
692 | "protocol": "http",
693 | "host": [
694 | "sso",
695 | "cdk8s",
696 | "com"
697 | ],
698 | "port": "9091",
699 | "path": [
700 | "sso",
701 | "oauth",
702 | "token"
703 | ]
704 | }
705 | },
706 | "response": []
707 | }
708 | ],
709 | "_postman_isSubFolder": true
710 | },
711 | {
712 | "name": "其他",
713 | "item": [
714 | {
715 | "name": "Actuator-修改 log 输出级别",
716 | "request": {
717 | "auth": {
718 | "type": "noauth"
719 | },
720 | "method": "POST",
721 | "header": [
722 | {
723 | "key": "Content-Type",
724 | "value": "application/json"
725 | }
726 | ],
727 | "body": {
728 | "mode": "raw",
729 | "raw": "{\"configuredLevel\": \"INFO\"}"
730 | },
731 | "url": {
732 | "raw": "http://sso.cdk8s.com:19091/tkey-actuator/actuator/loggers/com.cdk8s",
733 | "protocol": "http",
734 | "host": [
735 | "sso",
736 | "cdk8s",
737 | "com"
738 | ],
739 | "port": "19091",
740 | "path": [
741 | "tkey-actuator",
742 | "actuator",
743 | "loggers",
744 | "com.cdk8s"
745 | ]
746 | }
747 | },
748 | "response": []
749 | }
750 | ],
751 | "_postman_isSubFolder": true
752 | }
753 | ]
754 | }
755 | ]
756 | }
--------------------------------------------------------------------------------
/deployment/deployment-core.md:
--------------------------------------------------------------------------------
1 |
2 | # TKey 环境
3 |
4 | - CentOS 7.5 x64
5 |
6 | ## 修改 SSH 端口
7 |
8 | - 配置文件介绍(记得先备份):`sudo vim /etc/ssh/sshd_config`
9 | - 打开这一行注释:Port 22
10 | - 自定义端口选择建议在万位的端口,如:10000-65535之间,假设这里我改为 52221
11 | - CentOS 7:添加端口:`firewall-cmd --zone=public --add-port=52221/tcp --permanent`
12 | - 重启防火墙:`firewall-cmd --reload`
13 | - CentOS 7 命令:`systemctl restart sshd.service`
14 |
15 | ## 安装后的检测
16 |
17 | ```
18 | docker --version && docker-compose --version && java -version && mvn -v && mysql --version && redis-server --version && node -v && npm -v && nginx -V
19 | ```
20 |
21 |
22 | ## 设置免密登录
23 |
24 | - 在 A 机器上输入命令:`ssh-keygen`
25 | - 根据提示回车,共有三次交互提示,都回车即可。
26 | - 生成的密钥目录在:**/root/.ssh**
27 | - 写入:`cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys`
28 | - 测试:`ssh localhost`
29 |
30 | ## 安装 ansible
31 |
32 | - CentOS:`sudo yum install -y ansible`
33 | - 查看版本:`ansible --version`
34 | - 编辑配置文件:`vim /etc/ansible/hosts`,在文件尾部添加:
35 | - 查看自己的内网 ip:`ifconfig`,假设是:172.16.16.4
36 |
37 | ```
38 | [local]
39 | 172.16.16.4 ansible_ssh_port=52221
40 | ```
41 |
42 | - 让远程所有主机都执行 `ps` 命令,输出如下
43 |
44 | ```
45 | ansible all -a 'ps'
46 | ```
47 |
48 |
49 | ## 基础设置
50 |
51 | - 禁用
52 | - firewalld
53 | - selinux
54 | - swap
55 | - 安装
56 | - zip unzip lrzsz git wget htop deltarpm
57 | - zsh vim
58 | - docker docker-compose
59 |
60 | - 创建脚本文件:`vim /opt/1-install-basic-playbook.yml`
61 |
62 | ```
63 | - hosts: all
64 | remote_user: root
65 | tasks:
66 | - name: Disable SELinux at next reboot
67 | selinux:
68 | state: disabled
69 |
70 | - name: disable firewalld
71 | shell: "{{ item }}"
72 | with_items:
73 | - systemctl stop firewalld
74 | - systemctl disable firewalld
75 | - echo "vm.swappiness = 0" >> /etc/sysctl.conf
76 | - swapoff -a
77 | - sysctl -w vm.swappiness=0
78 |
79 | - name: install-epel
80 | shell: "{{ item }}"
81 | with_items:
82 | - yum install -y epel-release
83 |
84 | - name: install-basic
85 | shell: "{{ item }}"
86 | with_items:
87 | - yum install -y zip unzip lrzsz git wget htop deltarpm
88 |
89 | - name: install zsh oh-my-zsh
90 | shell: "{{ item }}"
91 | with_items:
92 | - yum install -y zsh
93 | - wget https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh -O - | sh
94 | - chsh -s /bin/zsh root
95 |
96 | - name: install-vim
97 | shell: "{{ item }}"
98 | with_items:
99 | - yum install -y vim
100 | - curl https://gitee.com/cdk8s_org/vim-for-server/raw/master/vimrc > ~/.vimrc
101 |
102 | - name: install-docker
103 | shell: "{{ item }}"
104 | with_items:
105 | - yum install -y yum-utils device-mapper-persistent-data lvm2
106 | - yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
107 | - yum makecache fast
108 | - yum install -y docker-ce docker-ce-cli containerd.io
109 | - systemctl start docker.service
110 |
111 | - name: create /etc/docker directory
112 | file:
113 | path: /etc/docker
114 | state: directory
115 |
116 | - name: create daemon.json file
117 | file:
118 | path=/etc/docker/{{ item }}
119 | state=touch
120 | mode=777
121 | with_items:
122 | - daemon.json
123 |
124 | - name: set docker registry mirrors
125 | blockinfile:
126 | path: /etc/docker/daemon.json
127 | marker: ""
128 | block: |
129 | {
130 | "registry-mirrors": [
131 | "https://ldhc17y9.mirror.aliyuncs.com",
132 | "https://hub-mirror.c.163.com",
133 | "https://mirror.baidubce.com",
134 | "https://docker.mirrors.ustc.edu.cn"
135 | ]
136 | }
137 |
138 | - name: restart docekr
139 | shell: "{{ item }}"
140 | with_items:
141 | - systemctl daemon-reload
142 | - systemctl restart docker
143 |
144 | - name: install-docker-compose
145 | shell: "{{ item }}"
146 | with_items:
147 | - curl -L https://get.daocloud.io/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
148 | - chmod +x /usr/local/bin/docker-compose
149 | - docker-compose --version
150 | - systemctl restart docker.service
151 | - systemctl enable docker.service
152 | ```
153 |
154 | - docker compose 最新版本好可以看:
155 | - 执行:`ansible-playbook /opt/1-install-basic-playbook.yml`
156 |
157 | ## 离线安装 jdk
158 |
159 | - 下载 jdk 到 /opt 目录下
160 | - 创建脚本文件:`vim /opt/2-jdk8-playbook.yml`
161 |
162 | ```
163 | - hosts: all
164 | remote_user: root
165 | vars:
166 | java_install_folder: /usr/local
167 | file_name: jdk-8u261-linux-x64.tar.gz
168 | tasks:
169 | - name: copy jdk
170 | copy:
171 | src=/opt/{{ file_name }}
172 | dest={{ java_install_folder }}
173 |
174 | - name: tar jdk
175 | shell:
176 | chdir={{ java_install_folder }}
177 | tar zxf {{ file_name }}
178 |
179 | - name: set JAVA_HOME
180 | blockinfile:
181 | path: /root/.zshrc
182 | marker: "#{mark} JDK ENV"
183 | block: |
184 | JAVA_HOME={{ java_install_folder }}/jdk1.8.0_261
185 | JRE_HOME=$JAVA_HOME/jre
186 | PATH=$PATH:$JAVA_HOME/bin
187 | CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
188 | export JAVA_HOME
189 | export JRE_HOME
190 | export PATH
191 | export CLASSPATH
192 |
193 | - name: source zshrc
194 | shell: source /root/.zshrc
195 |
196 | - name: remove tar.gz file
197 | file:
198 | state: absent
199 | path: "{{ java_install_folder }}/{{ file_name }}"
200 | ```
201 |
202 |
203 | - 执行命令:`ansible-playbook /opt/2-jdk8-playbook.yml`
204 |
205 |
206 |
207 | ## 安装 maven
208 |
209 |
210 | - 把 maven 放到 /opt 目录下
211 | - 创建脚本文件:`vim /opt/3-maven-playbook.yml`
212 |
213 | ```
214 | - hosts: all
215 | remote_user: root
216 | vars:
217 | maven_install_folder: /usr/local
218 | file_name: apache-maven-3.6.3-bin.zip
219 | tasks:
220 | - name: copy maven
221 | copy:
222 | src=/opt/{{ file_name }}
223 | dest={{ maven_install_folder }}
224 |
225 | - name: unzip maven
226 | shell:
227 | chdir={{ maven_install_folder }}
228 | unzip {{ file_name }}
229 |
230 | - name: set MAVEN_HOME
231 | blockinfile:
232 | path: /root/.zshrc
233 | marker: "#{mark} MAVEN ENV"
234 | block: |
235 | MAVEN_HOME={{ maven_install_folder }}/apache-maven-3.6.3
236 | M3_HOME={{ maven_install_folder }}/apache-maven-3.6.3
237 | M2_HOME={{ maven_install_folder }}/apache-maven-3.6.3
238 | PATH=$PATH:$M3_HOME/bin
239 | MAVEN_OPTS="-Xms256m -Xmx356m"
240 | export M3_HOME
241 | export M2_HOME
242 | export MAVEN_HOME
243 | export PATH
244 | export MAVEN_OPTS
245 |
246 | - name: source zshrc
247 | shell: source /root/.zshrc
248 |
249 | - name: remove zip file
250 | file:
251 | path: "{{ maven_install_folder }}/{{ file_name }}"
252 | state: absent
253 |
254 | - name: create local_maven_repository directory
255 | file:
256 | path: /opt/local_maven_repository
257 | state: directory
258 |
259 | - name: remove old settings.xml
260 | file:
261 | path: "{{ maven_install_folder }}/apache-maven-3.6.3/conf/settings.xml"
262 | state: absent
263 |
264 | - name: create settings.xml file
265 | file:
266 | path="{{ maven_install_folder }}/apache-maven-3.6.3/conf/{{ item }}"
267 | state=touch
268 | mode=777
269 | with_items:
270 | - settings.xml
271 |
272 | - name: set settings.xml aliyun
273 | blockinfile:
274 | path: "{{ maven_install_folder }}/apache-maven-3.6.3/conf/settings.xml"
275 | marker: ""
276 | block: |
277 |
278 |
281 |
282 |
283 | /opt/local_maven_repository
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 | aliyun
297 |
298 |
299 | aliyun
300 | http://maven.aliyun.com/nexus/content/groups/public/
301 |
302 | true
303 |
304 |
305 | true
306 |
307 |
308 |
309 |
310 |
311 | aliyun
312 | http://maven.aliyun.com/nexus/content/groups/public/
313 |
314 | true
315 |
316 |
317 | true
318 |
319 |
320 |
321 |
322 |
323 | maven
324 |
325 |
326 | maven
327 | https://repo.maven.apache.org/maven2/
328 |
329 | true
330 |
331 |
332 | true
333 |
334 |
335 |
336 |
337 |
338 | maven
339 | https://repo.maven.apache.org/maven2/
340 |
341 | true
342 |
343 |
344 | true
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 | aliyun
353 |
354 |
355 |
356 | ```
357 |
358 |
359 | - 执行命令:`ansible-playbook /opt/3-maven-playbook.yml`
360 |
361 |
362 | ## 安装 node
363 |
364 | - 创建脚本文件:`vim /opt/4-node-playbook.yml`
365 |
366 | ```
367 | - hosts: all
368 | remote_user: root
369 | tasks:
370 | - name: remove the nodejs
371 | yum:
372 | name: nodejs
373 | state: absent
374 |
375 | - name: remove the npm
376 | yum:
377 | name: npm
378 | state: absent
379 |
380 | - name: curl node
381 | shell: "curl --silent --location https://rpm.nodesource.com/setup_12.x | sudo bash -"
382 |
383 | - name: install node
384 | shell: "{{ item }}"
385 | with_items:
386 | - yum -y install nodejs
387 |
388 | - name: curl yarn
389 | shell: "curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo"
390 |
391 | - name: install yarn
392 | shell: "{{ item }}"
393 | with_items:
394 | - yum -y install yarn
395 | ```
396 |
397 |
398 | - 执行命令:`ansible-playbook /opt/4-node-playbook.yml`
399 |
400 | ## 安装原生 MySQL 5.7(可选 Docker)
401 |
402 | - 创建脚本文件:`vim /opt/5-mysql-playbook.yml`
403 |
404 | ```
405 | - hosts: all
406 | remote_user: root
407 | tasks:
408 | - name: remove the mariadb
409 | yum:
410 | name: mariadb
411 | state: absent
412 |
413 | - name: install mysql 1
414 | shell: "{{ item }}"
415 | with_items:
416 | - wget http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
417 | - yum localinstall -y mysql57-community-release-el7-11.noarch.rpm
418 |
419 | - name: install mysql 2
420 | yum:
421 | name: mysql-community-server
422 |
423 | - name: remove old /etc/my.cnf
424 | file:
425 | path: "/etc/my.cnf"
426 | state: absent
427 |
428 | - name: create my.cnf file
429 | file:
430 | path="/etc/{{ item }}"
431 | state=touch
432 | mode=777
433 | with_items:
434 | - my.cnf
435 |
436 | - name: set my.cnf
437 | blockinfile:
438 | path: /etc/my.cnf
439 | marker: ""
440 | block: |
441 | [mysql]
442 | default-character-set = utf8mb4
443 | [mysqld]
444 | max_connections = 500
445 | datadir = /var/lib/mysql
446 | socket = /var/lib/mysql/mysql.sock
447 | bind-address = 127.0.0.1
448 | symbolic-links=0
449 | log-error=/var/log/mysqld.log
450 | pid-file=/var/run/mysqld/mysqld.pid
451 | default-storage-engine = InnoDB
452 | collation-server = utf8mb4_unicode_520_ci
453 | init_connect = 'SET NAMES utf8mb4'
454 | character-set-server = utf8mb4
455 | lower_case_table_names = 1
456 | max_allowed_packet = 50M
457 | sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
458 |
459 | - name: enable mysql
460 | shell: "{{ item }}"
461 | with_items:
462 | - systemctl enable mysqld.service
463 | - systemctl restart mysqld.service
464 | ```
465 |
466 | - 执行命令:`ansible-playbook /opt/5-mysql-playbook.yml`
467 |
468 |
469 |
470 | ## 安装原生 Redis 5(可选 Docker)
471 |
472 |
473 |
474 | - 创建脚本文件:`vim /opt/6-redis-playbook.yml`
475 |
476 | ```
477 | - hosts: all
478 | remote_user: root
479 | tasks:
480 | - name: install redis
481 | yum:
482 | name: redis
483 |
484 | - name: remove old /etc/redis.conf
485 | file:
486 | path: "/etc/redis.conf"
487 | state: absent
488 |
489 | - name: create /etc/redis.conf file
490 | file:
491 | path="/etc/{{ item }}"
492 | state=touch
493 | mode=777
494 | with_items:
495 | - redis.conf
496 |
497 | - name: set redis.conf
498 | blockinfile:
499 | path: /etc/redis.conf
500 | marker: ""
501 | block: |
502 | bind 0.0.0.0
503 | requirepass adgredis123456
504 | protected-mode yes
505 | port 6379
506 | tcp-backlog 511
507 | timeout 0
508 | tcp-keepalive 300
509 | daemonize no
510 | supervised no
511 | pidfile /var/run/redis_6379.pid
512 | loglevel notice
513 | logfile /var/log/redis/redis.log
514 | databases 16
515 | save 900 1
516 | save 300 10
517 | save 60 10000
518 | stop-writes-on-bgsave-error yes
519 | rdbcompression yes
520 | rdbchecksum yes
521 | dbfilename dump.rdb
522 | dir /var/lib/redis
523 | slave-serve-stale-data yes
524 | slave-read-only yes
525 | repl-diskless-sync no
526 | repl-diskless-sync-delay 5
527 | repl-disable-tcp-nodelay no
528 | slave-priority 100
529 | appendonly no
530 | appendfilename "appendonly.aof"
531 | appendfsync everysec
532 | no-appendfsync-on-rewrite no
533 | auto-aof-rewrite-percentage 100
534 | auto-aof-rewrite-min-size 64mb
535 | aof-load-truncated yes
536 | lua-time-limit 5000
537 | slowlog-log-slower-than 10000
538 | slowlog-max-len 128
539 | latency-monitor-threshold 0
540 | notify-keyspace-events ""
541 | hash-max-ziplist-entries 512
542 | hash-max-ziplist-value 64
543 | list-max-ziplist-size -2
544 | list-compress-depth 0
545 | set-max-intset-entries 512
546 | zset-max-ziplist-entries 128
547 | zset-max-ziplist-value 64
548 | hll-sparse-max-bytes 3000
549 | activerehashing yes
550 | client-output-buffer-limit normal 0 0 0
551 | client-output-buffer-limit slave 256mb 64mb 60
552 | client-output-buffer-limit pubsub 32mb 8mb 60
553 | hz 10
554 | aof-rewrite-incremental-fsync yes
555 |
556 | - name: enable redis
557 | shell: "{{ item }}"
558 | with_items:
559 | - systemctl enable redis
560 | - systemctl restart redis
561 | ```
562 |
563 | - 执行命令:`ansible-playbook /opt/6-redis-playbook.yml`
564 |
565 |
566 | -------------------------------------------------------------------
567 |
568 | ## 安装 Jenkins
569 |
570 | - 创建脚本文件:`vim /opt/jenkins-playbook.yml`
571 |
572 | ```
573 | - hosts: all
574 | remote_user: root
575 | tasks:
576 | - name: wget
577 | shell: wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
578 |
579 | - name: rpm import
580 | shell: rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
581 |
582 | - name: install
583 | shell: yum install -y jenkins
584 | ```
585 |
586 | - 执行命令:`ansible-playbook /opt/jenkins-playbook.yml`
587 | - 在安装完默认推荐的插件后还需要额外安装:
588 | - `Maven Integration`
589 | - 设置 `全局工具配置` [点击我查看设置方法](https://upload-images.jianshu.io/upload_images/19119711-17eac75f51516b69.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
590 |
591 | -------------------------------------------------------------------
592 |
593 | ## 安装 Redis 5.x(Docker)
594 |
595 | ```
596 | mkdir -p /data/docker/redis/conf /data/docker/redis/db
597 | chmod -R 777 /data/docker/redis
598 | ```
599 |
600 | ```
601 | 创建配置文件:
602 | vim /data/docker/redis/conf/redis.conf
603 |
604 |
605 |
606 | bind 0.0.0.0
607 | requirepass 123456
608 | protected-mode yes
609 |
610 | port 6379
611 | tcp-backlog 511
612 | timeout 0
613 | tcp-keepalive 300
614 | daemonize no
615 | supervised no
616 | pidfile /data/redis_6379.pid
617 | loglevel notice
618 | logfile ""
619 | databases 16
620 | always-show-logo yes
621 | save 900 1
622 | save 300 10
623 | save 60 10000
624 | stop-writes-on-bgsave-error yes
625 | rdbcompression yes
626 | rdbchecksum yes
627 | dbfilename dump.rdb
628 | dir /data
629 | replica-serve-stale-data yes
630 | replica-read-only yes
631 | repl-diskless-sync no
632 | repl-diskless-sync-delay 5
633 | repl-disable-tcp-nodelay no
634 | replica-priority 100
635 | lazyfree-lazy-eviction no
636 | lazyfree-lazy-expire no
637 | lazyfree-lazy-server-del no
638 | replica-lazy-flush no
639 | appendonly no
640 | appendfilename "appendonly.aof"
641 | appendfsync everysec
642 | no-appendfsync-on-rewrite no
643 | auto-aof-rewrite-percentage 100
644 | auto-aof-rewrite-min-size 64mb
645 | aof-load-truncated yes
646 | aof-use-rdb-preamble yes
647 | lua-time-limit 5000
648 | slowlog-log-slower-than 10000
649 | slowlog-max-len 128
650 | latency-monitor-threshold 0
651 | notify-keyspace-events ""
652 | hash-max-ziplist-entries 512
653 | hash-max-ziplist-value 64
654 | list-max-ziplist-size -2
655 | list-compress-depth 0
656 | set-max-intset-entries 512
657 | zset-max-ziplist-entries 128
658 | zset-max-ziplist-value 64
659 | hll-sparse-max-bytes 3000
660 | stream-node-max-bytes 4096
661 | stream-node-max-entries 100
662 | activerehashing yes
663 | client-output-buffer-limit normal 0 0 0
664 | client-output-buffer-limit replica 256mb 64mb 60
665 | client-output-buffer-limit pubsub 32mb 8mb 60
666 | hz 10
667 | dynamic-hz yes
668 | aof-rewrite-incremental-fsync yes
669 | rdb-save-incremental-fsync yes
670 | ```
671 |
672 | - 启动镜像:
673 |
674 | ```
675 | docker run \
676 | --name cdk8s-redis \
677 | --restart always \
678 | -d -it -p 6379:6379 \
679 | -v /data/docker/redis/conf/redis.conf:/etc/redis/redis.conf \
680 | -v /data/docker/redis/db:/data \
681 | redis:5 \
682 | redis-server /etc/redis/redis.conf
683 | ```
684 |
685 | -------------------------------------------------------------------
686 |
687 | ## 安装 MySQL(Docker)
688 |
689 | ```
690 | mkdir -p /data/docker/mysql/datadir /data/docker/mysql/conf /data/docker/mysql/log
691 | ```
692 |
693 | ```
694 | 创建配置文件:
695 | vim /data/docker/mysql/conf/mysql-1.cnf
696 |
697 | # 该编码设置是我自己配置的
698 | [mysql]
699 | default-character-set = utf8mb4
700 |
701 | # 下面内容是 docker mysql 默认的 start
702 | [mysqld]
703 | max_connections = 500
704 | pid-file = /var/run/mysqld/mysqld.pid
705 | socket = /var/run/mysqld/mysqld.sock
706 | datadir = /var/lib/mysql
707 | #log-error = /var/log/mysql/error.log
708 | # By default we only accept connections from localhost
709 | #bind-address = 127.0.0.1
710 | # Disabling symbolic-links is recommended to prevent assorted security risks
711 | symbolic-links=0
712 | # 上面内容是 docker mysql 默认的 end
713 |
714 | # 下面开始的内容就是我自己配置的
715 | log-error=/var/log/mysql/error.log
716 | default-storage-engine = InnoDB
717 | collation-server = utf8mb4_unicode_520_ci
718 | init_connect = 'SET NAMES utf8mb4'
719 | character-set-server = utf8mb4
720 | # 表名大小写敏感 0 是区分大小写,1 是不分区,全部采用小写
721 | lower_case_table_names = 1
722 | max_allowed_packet = 50M
723 | sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
724 |
725 | # 避免在 dump 命令中加上密码后提示:Using a password on the command line interface can be insecure
726 | [mysqldump]
727 | user=root
728 | password=123456
729 | ```
730 |
731 | ```
732 | chmod -R 777 /data/docker/mysql/datadir /data/docker/mysql/log
733 | chown -R 0:0 /data/docker/mysql/conf
734 | ```
735 |
736 |
737 | ```
738 | docker run \
739 | --name cdk8s-mysql \
740 | --restart always \
741 | -d \
742 | -p 3306:3306 \
743 | -v /data/docker/mysql/datadir:/var/lib/mysql \
744 | -v /data/docker/mysql/log:/var/log/mysql \
745 | -v /data/docker/mysql/conf:/etc/mysql/conf.d \
746 | -e MYSQL_ROOT_PASSWORD=123456 \
747 | mysql:5.7
748 | ```
749 |
750 | -------------------------------------------------------------------
751 |
752 |
753 | ## 安装 Prometheus(Docker)
754 |
755 | ```
756 |
757 | 创建配置文件:
758 | mkdir -p /data/docker/prometheus/conf && vim /data/docker/prometheus/conf/prometheus.yml
759 | chmod -R 777 /data/docker/prometheus
760 |
761 | # my global config
762 | global:
763 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
764 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
765 | # scrape_timeout is set to the global default (10s).
766 |
767 | # Alertmanager configuration
768 | alerting:
769 | alertmanagers:
770 | - static_configs:
771 | - targets:
772 | # - alertmanager:9093
773 |
774 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
775 | rule_files:
776 | # - "first_rules.yml"
777 | # - "second_rules.yml"
778 |
779 |
780 | scrape_configs:
781 | - job_name: 'cdk8s-sso'
782 | metrics_path: '/tkey-actuator/actuator/prometheus'
783 | static_configs:
784 | - targets: ['172.16.16.4:19091']
785 | ```
786 |
787 |
788 | - 启动
789 |
790 | ```
791 | docker run \
792 | -d \
793 | --name cdk8s-prometheus \
794 | --restart always \
795 | -p 9090:9090 \
796 | -v /data/docker/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml \
797 | prom/prometheus
798 | ```
799 |
800 | -------------------------------------------------------------------
801 |
802 |
803 | ## 安装 Grafana(Docker)
804 |
805 |
806 | ```
807 | mkdir -p /data/docker/grafana/data
808 | chmod -R 777 /data/docker/grafana/data
809 |
810 | docker run \
811 | -d \
812 | --name cdk8s-grafana \
813 | --restart always \
814 | -p 3000:3000 \
815 | -v /data/docker/grafana/data:/var/lib/grafana \
816 | grafana/grafana
817 | ```
818 |
819 | -
820 | - 默认管理账号;admin,密码:admin,第一次登录后需要修改密码
821 |
822 | -------------------------------------------------------------------
823 |
824 | ## 安装 Portainer(Docker)
825 |
826 |
827 | ```
828 | mkdir -p /data/docker/portainer
829 | chmod -R 777 /data/docker/portainer
830 | ```
831 |
832 | - 创建文件:`vim docker-compose.yml`
833 |
834 | ```
835 | version: '3'
836 | services:
837 | portainer:
838 | container_name: portainer
839 | image: portainer/portainer
840 | volumes:
841 | - /data/docker/portainer:/data
842 | - /var/run/docker.sock:/var/run/docker.sock
843 | ports:
844 | - "9000:9000"
845 | ```
846 |
847 | - 启动:`docker-compose up -d`
848 | - 浏览器访问访问:
849 | - 第一次启动会让你创建用户名和密码。第二步就是配置管理哪里的 docker 容器,我这里选择:local
850 |
851 |
852 | -------------------------------------------------------------------
853 |
854 |
855 | ## 安装 Nginx(Docker)
856 |
857 | ```
858 | mkdir -p /data/docker/nginx/logs /data/docker/nginx/conf /data/docker/nginx/html
859 | chmod -R 777 /data/docker/nginx
860 | ```
861 |
862 | ```
863 | 创建配置文件:
864 | vim /data/docker/nginx/conf/nginx.conf
865 |
866 |
867 |
868 |
869 | worker_processes 1;
870 |
871 | events {
872 | worker_connections 1024;
873 | }
874 |
875 | http {
876 | include mime.types;
877 | default_type application/octet-stream;
878 |
879 | sendfile on;
880 | keepalive_timeout 65;
881 |
882 | gzip on;
883 | gzip_buffers 8 16k;
884 | gzip_min_length 512;
885 | gzip_disable "MSIE [1-6]\.(?!.*SV1)";
886 | gzip_http_version 1.1;
887 | gzip_types text/plain text/css application/javascript application/x-javascript application/json application/xml;
888 |
889 | server {
890 | listen 80;
891 | server_name localhost 127.0.0.1 191.112.221.203;
892 |
893 | location / {
894 | root /usr/share/nginx/html;
895 | index index.html index.htm;
896 | }
897 | }
898 | }
899 | ```
900 |
901 |
902 | - 运行容器:
903 |
904 | ```
905 | docker run \
906 | -d \
907 | --name cdk8s-nginx \
908 | --restart always \
909 | -p 80:80 \
910 | -v /data/docker/nginx/logs:/var/log/nginx \
911 | -v /data/docker/nginx/html:/data/html \
912 | -v /data/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
913 | nginx:1.17
914 | ```
915 |
916 | - 重新启动服务:`docker restart cdk8s-nginx`
917 |
918 | -------------------------------------------------------------------
919 |
920 |
921 |
922 | ## Jenkins pipeline (Docker 方式运行 tkey-sso-server)
923 |
924 | - **确保** 项目根目录有 Dockerfile 文件
925 | - 特别注意:
926 |
927 | ```
928 | 这两个大写的名词来自 Jenkins 全局工具配置中相应配置的 name 中填写的内容
929 | jdk 'JDK8'
930 | maven 'MAVEN3'
931 | ```
932 |
933 | ```
934 | pipeline {
935 | agent any
936 |
937 | /*=======================================工具环境修改-start=======================================*/
938 | tools {
939 | jdk 'JDK8'
940 | maven 'MAVEN3'
941 | }
942 | /*=======================================工具环境修改-end=======================================*/
943 |
944 | options {
945 | timestamps()
946 | disableConcurrentBuilds()
947 | buildDiscarder(logRotator(
948 | numToKeepStr: '20',
949 | daysToKeepStr: '30',
950 | ))
951 | }
952 |
953 | /*=======================================常修改变量-start=======================================*/
954 |
955 | environment {
956 | gitUrl = "https://github.com/cdk8s/tkey.git"
957 | branchName = "master"
958 | giteeCredentialsId = "cdk8s-github"
959 | projectWorkSpacePath = "${env.WORKSPACE}"
960 | projectBuildTargetPath = "${projectWorkSpacePath}/target"
961 |
962 |
963 | dockerImageName = "harbor.cdk8s.com/tkey/${env.JOB_NAME}:${env.BUILD_NUMBER}"
964 | dockerContainerName = "${env.JOB_NAME}"
965 | inHostPort = "9091"
966 | inHostPortByActuator = "19091"
967 | inDockerAndJavaPort = "9091"
968 | inDockerAndJavaPortByActuator = "19091"
969 | inHostLogPath = "/data/logs/${dockerContainerName}/${env.BUILD_NUMBER}"
970 | inDockerLogPath = "/logs"
971 | dockerRunParam = "--name=${dockerContainerName} --hostname=${dockerContainerName} -v /etc/hosts:/etc/hosts -v ${inHostLogPath}:${inDockerLogPath} --restart=always -p ${inHostPort}:${inDockerAndJavaPort} -p ${inHostPortByActuator}:${inDockerAndJavaPortByActuator} -e SPRING_PROFILES_ACTIVE=test -e SERVER_PORT=${inHostPort} -e SPRING_REDIS_HOST=redis.cdk8s.com -e SPRING_REDIS_PASSWORD=123456 -e TKEY_NODE_NUMBER=12"
972 | }
973 |
974 | /*=======================================常修改变量-end=======================================*/
975 |
976 | stages {
977 |
978 | stage('Pre Env') {
979 | steps {
980 | echo "======================================项目名称 = ${env.JOB_NAME}"
981 | echo "======================================项目 URL = ${gitUrl}"
982 | echo "======================================项目分支 = ${branchName}"
983 | echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}"
984 | echo "======================================项目空间文件夹路径 = ${projectWorkSpacePath}"
985 | echo "======================================项目 build 后 jar 路径 = ${projectBuildTargetPath}"
986 | echo "======================================Docker 镜像名称 = ${dockerImageName}"
987 | echo "======================================Docker 容器名称 = ${dockerContainerName}"
988 | }
989 | }
990 |
991 | stage('Git Clone'){
992 | steps {
993 | git branch: "${branchName}",
994 | credentialsId: "${giteeCredentialsId}",
995 | url: "${gitUrl}"
996 | }
997 | }
998 |
999 | stage('Maven Clean') {
1000 | steps {
1001 | sh "mvn clean"
1002 | }
1003 | }
1004 |
1005 | stage('Maven Package') {
1006 | steps {
1007 | sh "mvn package -DskipTests"
1008 | }
1009 | }
1010 |
1011 | stage('构建 Docker 镜像') {
1012 | steps {
1013 | sh """
1014 | cd ${projectWorkSpacePath}
1015 |
1016 | docker build -t ${dockerImageName} ./
1017 | """
1018 | }
1019 | }
1020 |
1021 | stage('运行 Docker 镜像') {
1022 | steps {
1023 | sh """
1024 | docker stop ${dockerContainerName} | true
1025 |
1026 | docker rm -f ${dockerContainerName} | true
1027 |
1028 | docker run -d ${dockerRunParam} ${dockerImageName}
1029 | """
1030 | }
1031 | }
1032 |
1033 |
1034 | }
1035 | }
1036 | ```
1037 |
1038 |
1039 |
1040 |
1041 |
1042 | ## Jenkins pipeline (Docker 方式运行 tkey-sso-client-management 后端)
1043 |
1044 | - **确保** 项目根目录有 Dockerfile 文件
1045 | - 特别注意:
1046 |
1047 | ```
1048 | 这两个大写的名词来自 Jenkins 全局工具配置中相应配置的 name 中填写的内容
1049 | jdk 'JDK8'
1050 | maven 'MAVEN3'
1051 | ```
1052 |
1053 | ```
1054 | pipeline {
1055 | agent any
1056 |
1057 | /*=======================================工具环境修改-start=======================================*/
1058 | tools {
1059 | jdk 'JDK8'
1060 | maven 'MAVEN3'
1061 | }
1062 | /*=======================================工具环境修改-end=======================================*/
1063 |
1064 | options {
1065 | timestamps()
1066 | disableConcurrentBuilds()
1067 | buildDiscarder(logRotator(
1068 | numToKeepStr: '20',
1069 | daysToKeepStr: '30',
1070 | ))
1071 | }
1072 |
1073 | /*=======================================常修改变量-start=======================================*/
1074 |
1075 | environment {
1076 | gitUrl = "https://github.com/cdk8s/tkey-sso-client-management.git"
1077 | branchName = "master"
1078 | giteeCredentialsId = "cdk8s-github"
1079 | projectWorkSpacePath = "${env.WORKSPACE}"
1080 | projectBuildTargetPath = "${projectWorkSpacePath}/target"
1081 |
1082 |
1083 | dockerImageName = "harbor.cdk8s.com/tkey/${env.JOB_NAME}:${env.BUILD_NUMBER}"
1084 | dockerContainerName = "${env.JOB_NAME}"
1085 | inHostPort = "9095"
1086 | inHostPortByActuator = "19095"
1087 | inDockerAndJavaPort = "9095"
1088 | inDockerAndJavaPortByActuator = "19095"
1089 | inHostLogPath = "/data/logs/${dockerContainerName}/${env.BUILD_NUMBER}"
1090 | inDockerLogPath = "/logs"
1091 | dockerRunParam = "--name=${dockerContainerName} --hostname=${dockerContainerName} -v /etc/hosts:/etc/hosts -v ${inHostLogPath}:${inDockerLogPath} --restart=always -p ${inHostPort}:${inDockerAndJavaPort} -p ${inHostPortByActuator}:${inDockerAndJavaPortByActuator} -e SPRING_PROFILES_ACTIVE=test -e SERVER_PORT=${inHostPort} -e SPRING_REDIS_HOST=redis.cdk8s.com -e SPRING_REDIS_PASSWORD=123456"
1092 | }
1093 |
1094 | /*=======================================常修改变量-end=======================================*/
1095 |
1096 | stages {
1097 |
1098 | stage('Pre Env') {
1099 | steps {
1100 | echo "======================================项目名称 = ${env.JOB_NAME}"
1101 | echo "======================================项目 URL = ${gitUrl}"
1102 | echo "======================================项目分支 = ${branchName}"
1103 | echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}"
1104 | echo "======================================项目空间文件夹路径 = ${projectWorkSpacePath}"
1105 | echo "======================================项目 build 后 jar 路径 = ${projectBuildTargetPath}"
1106 | echo "======================================Docker 镜像名称 = ${dockerImageName}"
1107 | echo "======================================Docker 容器名称 = ${dockerContainerName}"
1108 | }
1109 | }
1110 |
1111 | stage('Git Clone'){
1112 | steps {
1113 | git branch: "${branchName}",
1114 | credentialsId: "${giteeCredentialsId}",
1115 | url: "${gitUrl}"
1116 | }
1117 | }
1118 |
1119 | stage('Maven Clean') {
1120 | steps {
1121 | sh "mvn clean"
1122 | }
1123 | }
1124 |
1125 | stage('Maven Package') {
1126 | steps {
1127 | sh "mvn package -DskipTests"
1128 | }
1129 | }
1130 |
1131 | stage('构建 Docker 镜像') {
1132 | steps {
1133 | sh """
1134 | cd ${projectWorkSpacePath}
1135 |
1136 | docker build -t ${dockerImageName} ./
1137 | """
1138 | }
1139 | }
1140 |
1141 | stage('运行 Docker 镜像') {
1142 | steps {
1143 | sh """
1144 | docker stop ${dockerContainerName} | true
1145 |
1146 | docker rm -f ${dockerContainerName} | true
1147 |
1148 | docker run -d ${dockerRunParam} ${dockerImageName}
1149 | """
1150 | }
1151 | }
1152 |
1153 |
1154 | }
1155 | }
1156 | ```
1157 |
1158 |
1159 |
1160 | ## Jenkins pipeline (Docker 方式运行 tkey-sso-client-management 前端)
1161 |
1162 |
1163 | ```
1164 | pipeline {
1165 | agent any
1166 |
1167 | options {
1168 | timestamps()
1169 | disableConcurrentBuilds()
1170 | buildDiscarder(logRotator(
1171 | numToKeepStr: '20',
1172 | daysToKeepStr: '30',
1173 | ))
1174 | }
1175 |
1176 | /*=======================================常修改变量-start=======================================*/
1177 |
1178 | environment {
1179 | gitUrl = "https://github.com/cdk8s/tkey-sso-client-management-frontend.git"
1180 | branchName = "master"
1181 | giteeCredentialsId = "cdk8s-github"
1182 | projectBuildPath = "${env.WORKSPACE}/dist"
1183 | nginxHtmlRoot = "/data/docker/nginx/html/tkey-sso-client-management-frontend"
1184 | }
1185 |
1186 | /*=======================================常修改变量-end=======================================*/
1187 |
1188 | stages {
1189 |
1190 | stage('Pre Env') {
1191 | steps {
1192 | echo "======================================项目名称 = ${env.JOB_NAME}"
1193 | echo "======================================项目 URL = ${gitUrl}"
1194 | echo "======================================项目分支 = ${branchName}"
1195 | echo "======================================当前编译版本号 = ${env.BUILD_NUMBER}"
1196 | echo "======================================项目 Build 文件夹路径 = ${projectBuildPath}"
1197 | echo "======================================项目 Nginx 的 ROOT 路径 = ${nginxHtmlRoot}"
1198 | }
1199 | }
1200 |
1201 | stage('Git Clone'){
1202 | steps {
1203 | git branch: "${branchName}",
1204 | credentialsId: "${giteeCredentialsId}",
1205 | url: "${gitUrl}"
1206 | }
1207 | }
1208 |
1209 | stage('YARN Install') {
1210 | steps {
1211 | sh "yarn install"
1212 | }
1213 | }
1214 |
1215 | stage('YARN Build') {
1216 | steps {
1217 | sh "yarn build:test"
1218 | }
1219 | }
1220 |
1221 | stage('Nginx Deploy') {
1222 | steps {
1223 | sh "rm -rf ${nginxHtmlRoot}/"
1224 | sh "cp -r ${projectBuildPath}/ ${nginxHtmlRoot}/"
1225 | }
1226 | }
1227 |
1228 |
1229 | }
1230 | }
1231 | ```
1232 |
1233 | -------------------------------------------------------------------
1234 |
1235 |
1236 | ## GoAccess
1237 |
1238 | - GoAccess 建议用本地安装
1239 | - 安装步骤过长,请参考我们的这篇文章:[GoAccess](https://github.com/cdk8s/cdk8s-team-style/blob/master/os/linux/goaccess.md)
1240 | - 创建目录:`mkdir -p /data/docker/nginx/html/report`
1241 | - 手动运行
1242 |
1243 | ```
1244 | goaccess -f /data/docker/nginx/logs/access.log --geoip-database=/opt/GeoLite2-City_20190820/GeoLite2-City.mmdb -p /etc/goaccess_log_conf_nginx.conf -o /data/docker/nginx/html/report/index.html
1245 | ```
1246 |
1247 | - 实时运行
1248 |
1249 | ```
1250 | goaccess -f /data/docker/nginx/logs/access.log --geoip-database=/opt/GeoLite2-City_20190820/GeoLite2-City.mmdb -p /etc/goaccess_log_conf_nginx.conf -o /data/docker/nginx/html/report/index.html --real-time-html --daemonize
1251 | ```
1252 |
1253 |
1254 | -------------------------------------------------------------------
1255 |
1256 |
1257 |
1258 | ## Nginx 最终配置
1259 |
1260 | - 因为 nginx 在 docker 里面,所以不能用 127.0.0.1
1261 |
1262 | ```
1263 | 配置文件:
1264 | vim /data/docker/nginx/conf/nginx.conf
1265 |
1266 |
1267 |
1268 | worker_processes 1;
1269 |
1270 | events {
1271 | worker_connections 1024;
1272 | }
1273 |
1274 | http {
1275 | include mime.types;
1276 | default_type application/octet-stream;
1277 |
1278 | charset utf8;
1279 |
1280 | log_format main '$remote_addr - $remote_user [$time_local] "$request" '
1281 | '$status $body_bytes_sent "$http_referer" '
1282 | '"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
1283 |
1284 | access_log /var/log/nginx/access.log main;
1285 | error_log /var/log/nginx/error.log;
1286 |
1287 |
1288 | sendfile on;
1289 | keepalive_timeout 65;
1290 |
1291 | gzip on;
1292 | gzip_buffers 8 16k;
1293 | gzip_min_length 512;
1294 | gzip_disable "MSIE [1-6]\.(?!.*SV1)";
1295 | gzip_http_version 1.1;
1296 | gzip_types text/plain text/css application/javascript application/x-javascript application/json application/xml;
1297 |
1298 | server {
1299 | listen 80;
1300 | server_name localhost 127.0.0.1 182.61.44.40;
1301 |
1302 | location /tkey-test {
1303 | return 601;
1304 | }
1305 |
1306 | location ^~ /upload {
1307 | root /home/root/sculptor-boot-backend-upload-dir;
1308 | autoindex on;
1309 | autoindex_exact_size off;
1310 | autoindex_localtime on;
1311 | }
1312 |
1313 | # 需要创建目录 /data/html/tkey-sso-client-management-frontend,里面存放 index.html 等静态文件
1314 | location ^~ /tkey-sso-client-management-frontend {
1315 | root /data/html;
1316 | index index.html;
1317 | try_files $uri /tkey-sso-client-management-frontend/index.html;
1318 | }
1319 |
1320 | location ^~ /sso-client-management/ {
1321 | proxy_pass http://172.16.16.4:9095;
1322 | proxy_redirect off;
1323 | proxy_set_header Host $host;
1324 | proxy_set_header X-Real-IP $remote_addr;
1325 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
1326 | proxy_set_header X-Forwarded-Proto $scheme;
1327 | }
1328 |
1329 | location ^~ /sso/ {
1330 | proxy_pass http://172.16.16.4:9091;
1331 | proxy_redirect off;
1332 | proxy_set_header Host $host;
1333 | proxy_set_header X-Real-IP $remote_addr;
1334 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
1335 | proxy_set_header X-Forwarded-Proto $scheme;
1336 | }
1337 |
1338 |
1339 | location ^~ /report {
1340 | root /data/html;
1341 | index index.html index.htm;
1342 | }
1343 |
1344 | location / {
1345 | root /usr/share/nginx/html;
1346 | index index.html index.htm;
1347 | }
1348 | }
1349 | }
1350 |
1351 | ```
1352 |
1353 | ## hosts 配置
1354 |
1355 |
1356 | ```
1357 | 172.16.16.4 sso.cdk8s.com
1358 | 172.16.16.4 test1.cdk8s.com
1359 | 172.16.16.4 test2.cdk8s.com
1360 | 172.16.16.4 redis.cdk8s.com
1361 | 172.16.16.4 mysql.cdk8s.com
1362 | 172.16.16.4 management.cdk8s.com
1363 | 172.16.16.4 tkey-sso-client-management
1364 | 172.16.16.4 tkey-sso
1365 | ```
--------------------------------------------------------------------------------