animeic 1 年之前
父节点
当前提交
00c52d397b
共有 11 个文件被更改,包括 481 次插入0 次删除
  1. 454 0
      casdoor用户认证.md
  2. 27 0
      work-note.md
  3. 二进制
      对象存储.png
  4. 二进制
      应用.png
  5. 二进制
      权限.png
  6. 二进制
      模型.png
  7. 二进制
      测试api.png
  8. 二进制
      短信配置.png
  9. 二进制
      第三方登录.png
  10. 二进制
      组织.png
  11. 二进制
      证书.png

+ 454 - 0
casdoor用户认证.md

@@ -0,0 +1,454 @@
+# casdoor 用户认证使用
+
+## 安装
+
+- 编译
+  1. [下载源码](https://github.com/casdoor/casdoor)
+  2. 编译后端服务:`go build .`
+  3. 编译前端:`yarn build`
+- 配置
+
+编写Dockerfile文件:
+
+```sh
+FROM alpine
+
+RUN echo -e https://mirrors.ustc.edu.cn/alpine/v3.15/main > /etc/apk/repositories \
+  && cat /etc/apk/repositories \
+# 设置时区为上海
+  && apk add tzdata && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
+  && echo "Asia/Shanghai" > /etc/timezone \
+  && apk del tzdata \
+# 解决apline 运行编译后的执行文件 not found错误
+# 由于alpine镜像使用的是musl libc而不是gnu libc,/lib64/ 是不存在的。但他们是兼容的,可以创建个软连接
+  && mkdir /lib64 \
+  && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
+
+WORKDIR /
+
+ADD web web
+ADD casdoor casdoor
+
+EXPOSE 8000
+
+ENTRYPOINT ["./casdoor"]
+```
+
+编写镜像构建脚本:
+
+```sh
+#!/bin/bash
+
+# 命名镜像
+repository_image="registry.cn-chengdu.aliyuncs.com/infish/pack-casdoor-auth:v1.0.0"
+
+# 删除本地已存在的镜像
+docker rmi $repository_image
+
+# 创建本地镜像
+docker build -t $repository_image .
+
+# push到镜像仓库,需要登陆对应docker仓库账号
+docker push $repository_image
+```
+
+编写docker-compose.yaml文件:
+
+```sh
+
+version: '3.8'
+
+# 网络
+networks:
+  default:
+    name: default-network
+    external: true
+
+services:
+  auth-casdoor:
+    image: "registry.cn-chengdu.aliyuncs.com/infish/pack-casdoor-auth:v1.0.0"
+    restart: always
+    ports:
+      - 36002:8000
+    volumes:
+      - ./conf:/conf
+    depends_on:
+        - auth-mysql
+
+  auth-mysql:
+    restart: always
+    # 5.7不支持中文
+    image: mysql:8
+    volumes:
+      - /data/auth/mysql:/var/lib/mysql
+    environment:
+      MYSQL_ROOT_PASSWORD: auth2023
+      MYSQL_DATABASE: casdoor
+    ports:
+      - 33306:3306
+```
+
+conf/app.conf文件:
+
+```sh
+ppname = casdoor
+httpport = 8000
+runmode = dev
+copyrequestbody = true
+driverName = mysql
+dataSourceName = root:auth2023@tcp(auth-mysql:3306)/
+dbName = casdoor
+# tableNamePrefix =
+# showSql = false
+# redisEndpoint =
+# defaultStorageProvider =
+# isCloudIntranet = false
+# authState = "casdoor"
+# socks5Proxy = "127.0.0.1:10808"
+# verificationCodeTimeout = 10
+# initScore = 2000
+# logPostOnly = true
+# origin =
+# staticBaseUrl = "https://auth3dqueen.oss-cn-beijing.aliyuncs.com/static"
+# isDemoMode = false
+# batchSize = 100
+# ldapServerPort = 389
+# languages = en,zh,es,fr,de,id,ja,ko,ru,vi
+# quota = {"organization": -1, "user": -1, "application": -1, "provider": -1}
+```
+
+启动服务:`docker compose up -d`
+
+配置nginx:
+
+```conf
+server {
+    listen 80;
+    listen [::]:80;
+    server_name auth.3dqueen.cloud;
+    rewrite ^(.*) https://$server_name$1 permanent;
+ }
+
+server {
+    listen 443 ssl http2;
+    listen [::]:443 ssl http2;
+    server_name auth.3dqueen.cloud;
+    #root /var/www/auth;
+
+    client_max_body_size 5M;
+    ssl_certificate "cert/9743199_auth.3dqueen.cloud.pem";
+    ssl_certificate_key "cert/9743199_auth.3dqueen.cloud.key";
+    ssl_session_cache shared:SSL:1m;
+    ssl_session_timeout 10m;
+    ssl_ciphers HIGH:!aNULL:!MD5;
+    ssl_prefer_server_ciphers on;
+
+
+    location / {
+        proxy_set_header    Host            $http_host;
+        proxy_set_header    X-Real-IP       $remote_addr;
+        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_redirect      off;
+        proxy_pass http://127.0.0.1:36002;
+    }
+
+}
+
+```
+
+## 配置应用
+
+访问nginx配置的域名,登录后配置组织和应用:`账号:admin 密码:123`
+
+组织配置:![组织配置](组织.png)
+应用配置:![应用配置](应用.png)
+
+## 认证
+
+配置证书:![证书配置](证书.png)
+
+下载证书、配置到后端:
+
+app.yaml:
+
+```yaml
+...
+Auth:
+  endpoint: https://auth.3dqueen.cloud
+  clientId:	9f22d6616ae14fe59dc4
+  clientSecret: b0fae13ca7e7eb1e4e6dc8fa50902eb7b6035049
+  certificate: token_jwt_key.pem
+  organizationName:	org_3dqueen_cloud
+  applicationName: app_boxcost
+```
+
+Dockerfile文件中添加:
+
+```Dockerfile
+...
+# 下载的证书
+ADD token_jwt_key.pem token_jwt_key.pem
+...
+```
+
+下载使用[casdoor-go-sdk](https://github.com/casdoor/casdoor-go-sdk)
+
+配置回调:`api/calback.go`
+
+```go
+// https://auth.3dqueen.cloud/login/oauth/authorize?client_id=9f22d6616ae14fe59dc4&redirect_uri=https://www.3dqueen.cloud/box/v1/boxcost/callback&response_type=code&scope=openid&state=STATE
+// 需要在第三方提供商配置回调 https://auth.3dqueen.cloud/callback
+func callback(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+	authConf := apictx.Svc.Conf.Auth
+	pemByte, err := os.ReadFile(authConf.Certificate)
+	if err != nil {
+		return nil, err
+	}
+	casdoorsdk.InitConfig(authConf.Endpoint, authConf.ClientId, authConf.ClientSecret, string(pemByte), authConf.OrganizationName, authConf.ApplicationName)
+	token, err := casdoorsdk.GetOAuthToken(c.Query("code"), c.Query("state"))
+	if err != nil {
+		fmt.Println(err)
+	}
+
+	fmt.Println(token.AccessToken)
+	claims, err := casdoorsdk.ParseJwtToken(token.AccessToken)
+	if err != nil {
+		fmt.Println(err)
+	}
+	fmt.Println(claims)
+	c.Redirect(http.StatusFound, "https://auth.3dqueen.cloud")
+
+	// claims.AccessToken = token.AccessToken
+	return nil, nil
+}
+
+```
+
+password方式获取token:`api/auth.go`
+
+```go
+func AuthToken(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+
+	authConf := apictx.Svc.Conf.Auth
+	// pemByte, err := os.ReadFile(authConf.Certificate)
+	// if err != nil {
+	// 	return nil, err
+	// }
+	// casdoorsdk.InitConfig(authConf.Endpoint, authConf.ClientId, authConf.ClientSecret, string(pemByte), authConf.OrganizationName, authConf.ApplicationName)
+
+	data := &AuthTOkenReq{
+		GrantType:    "password",
+		ClientId:     authConf.ClientId,
+		ClientSecret: authConf.ClientSecret,
+		UserName:     "sunsheng",
+		Password:     "ssxhyw2515",
+	}
+	dataByte, err := json.Marshal(data)
+	if err != nil {
+		return nil, err
+	}
+	fmt.Println(dataByte)
+
+	// 发送POST请求并将数据作为JSON提交
+	req, err := http.NewRequest("POST", fmt.Sprintf("%s/%s", authConf.Endpoint, "api/login/oauth/access_token"), bytes.NewBuffer(dataByte))
+	if err != nil {
+		panic(err)
+	}
+	req.Header.Set("Content-Type", "application/json")
+
+	client := &http.Client{}
+	resp, err := client.Do(req)
+	if err != nil {
+		panic(err)
+	}
+	defer resp.Body.Close()
+
+	var buf bytes.Buffer
+	_, err = buf.ReadFrom(resp.Body)
+	if err != nil {
+		panic(err)
+	}
+	buf.WriteTo(c.Writer)
+	// responseStr := buf.String()
+	// 打印响应内容
+	// fmt.Println(responseStr)
+
+	return nil, nil
+}
+```
+
+## 权限控制
+
+配置权限模型:![权限模型](模型.png)
+配置权限:![权限模型](权限.png)
+
+jwt中间件:`middleware/jwt.go`
+
+```go
+package middleware
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+	"time"
+
+	"github.com/casdoor/casdoor-go-sdk/casdoorsdk"
+	"github.com/gin-gonic/gin"
+)
+
+// JWTAuthMiddleware 基于JWT的认证中间件--验证用户是否登录
+func JWTAuthMiddleware() func(c *gin.Context) {
+	return func(c *gin.Context) {
+		authHeader := c.Request.Header.Get("authorization")
+		if authHeader == "" {
+			c.JSON(http.StatusUnauthorized, gin.H{
+				"code": 2003,
+				"msg":  "请求头中auth为空",
+			})
+			c.Abort()
+			return
+		}
+		// 按空格分割
+		parts := strings.Split(authHeader, ".")
+		if len(parts) != 3 {
+			c.JSON(http.StatusUnauthorized, gin.H{
+				"code": 2004,
+				"msg":  "请求头中auth格式有误",
+			})
+			c.Abort()
+			return
+		}
+		mc, err := casdoorsdk.ParseJwtToken(authHeader)
+		fmt.Println(mc.VerifyExpiresAt(time.Now(), false))
+		if err != nil {
+			fmt.Println(err)
+			c.JSON(http.StatusUnauthorized, gin.H{
+				"code": 2005,
+				"msg":  "无效的Token",
+			})
+			c.Abort()
+			return
+		}
+
+		// m := mc.(jwt.MapClaims)
+		// 将当前请求的username信息保存到请求的上下文c上
+		c.Set("uid", mc.User.Id)
+		c.Set("username", mc.User.Name)
+		c.Next() // 后续的处理函数可以用过c.Get("username")来获取当前请求的用户信息
+	}
+}
+
+```
+
+权限控制中间件:`middleware/pc.go`
+
+```go
+package middleware
+
+import (
+	"boxcost/conf"
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/casdoor/casdoor-go-sdk/casdoorsdk"
+	"github.com/gin-gonic/gin"
+)
+
+func PermissionControlMiddleware() func(c *gin.Context) {
+	return func(c *gin.Context) {
+		// 验证该用户是否可以访问该资源
+
+		permission := strings.Replace(c.Request.URL.String(), "/", "_", -1)
+
+		id := fmt.Sprintf("%s/%s%s", conf.AppConfig.Auth.OrganizationName, strings.ToLower(c.Request.Method), permission)
+		fmt.Println(id)
+		ok, err := casdoorsdk.Enforce(&casdoorsdk.PermissionRule{
+			Ptype: "p",
+			V0:    fmt.Sprintf("%s/%s", conf.AppConfig.Auth.OrganizationName, c.GetString("username")), // 请求实体
+			V1:    c.Request.URL.String(),                                                              // 请求资源主体 // /book/*
+			V2:    strings.ToLower(c.Request.Method),                                                   // 请求方法
+			Id:    id,
+		})
+		// roles
+		if err != nil {
+			c.JSON(http.StatusUnauthorized, gin.H{
+				"code": -1,
+				"msg":  err.Error(),
+			})
+			c.Abort()
+			return
+		}
+		if !ok {
+			c.JSON(http.StatusForbidden, gin.H{
+				"code": -1,
+				"msg":  "没有权限访问",
+			})
+			c.Abort()
+			return
+		}
+		c.Next()
+
+	}
+
+}
+
+```
+
+使用中间件:`api/api.go`
+
+```go
+...
+// GETJWT http Get 请求
+func (g GinRouter) GETJWT(path string, httpHandler JWTHander) {
+	g.group.GET(path, middleware.JWTAuthMiddleware(), middleware.PermissionControlMiddleware(), ResultJWTWrapper(httpHandler, g.svc))
+}
+
+// POSTJWT http POST 请求
+func (g GinRouter) POSTJWT(path string, httpHandler JWTHander) {
+	g.group.POST(path, middleware.JWTAuthMiddleware(), middleware.PermissionControlMiddleware(), ResultJWTWrapper(httpHandler, g.svc))
+}
+...
+```
+
+测试:`api/user.go`
+
+```go
+package api
+
+import (
+	"afina/conf"
+	"fmt"
+	"time"
+
+	"github.com/casdoor/casdoor-go-sdk/casdoorsdk"
+	"github.com/gin-gonic/gin"
+)
+
+func User(r *GinRouter) {
+	r.POSTJWT("/user/create", CreateUser)
+}
+
+func CreateUser(c *gin.Context, apictx *ApiSession) (interface{}, error) {
+	var user casdoorsdk.User
+	err := c.ShouldBindJSON(&user)
+	if err != nil {
+		fmt.Println(err)
+		return nil, err
+	}
+	user.SignupApplication = conf.AppConfig.Auth.ApplicationName
+	user.CreatedTime = time.Now().Format("2006-01-02T15:04:05-07:00")
+	user.Type = "normal-user"
+
+	return casdoorsdk.AddUser(&user)
+}
+```
+
+测试api:![测试api](测试api.png)
+
+## 其他
+
+配置短信:![短信配置](短信配置.png)
+第三方登录:![第三方登录配置](第三方登录.png)
+对象存储:![对象存储配置](对象存储.png)

+ 27 - 0
work-note.md

@@ -90,3 +90,30 @@
 1. 审核用户签字流程:用户可以设置签字账号,上传签字图片。
 2. 与前端对接3dshow2.0:修复与原有接口不兼容,修复bug和完善接口
 3. 其他项目组需要完成的工作
+
+### 2023-02-08
+
+1. 供应商多个分类
+2. 表格的实际金额依赖计价策略计算吗
+
+
+## 下载供应商所有单据
+
+1. 查询选定计划下的某供应商单据
+2. 查询该供应商单据是否全部完成
+   1. 已完成根据提交成本数计算
+   2. 未全部完成根据实际提交数计算实际金额
+3. 重写表格,提供pdf下载
+
+## 多个相同类型工序的处理
+
+1. 包装计价项目,与客户沟通需求,根据确定的需求更改功能
+   1. 生产计划业务流程的调整,数据结构调整
+   2. 新增成品采购相关接口
+   3. 根据调整修改单据表、生产成本表
+   4. 与前端对接更改功能,并持续跟进需求进行完善
+2. 数之鞋项目与前端对接,调整部分功能。
+3. 油封培训项目,制作win7本地包后台系统部署包
+4. 调研以图搜图功能
+   1. 初步确定towhee+milvus来实现
+   2. 部署服务和测试

二进制
对象存储.png


二进制
应用.png


二进制
权限.png


二进制
模型.png


二进制
测试api.png


二进制
短信配置.png


二进制
第三方登录.png


二进制
组织.png


二进制
证书.png