animeic 1 tahun lalu
induk
melakukan
00c52d397b
11 mengubah file dengan 481 tambahan dan 0 penghapusan
  1. 454 0
      casdoor用户认证.md
  2. 27 0
      work-note.md
  3. TEMPAT SAMPAH
      对象存储.png
  4. TEMPAT SAMPAH
      应用.png
  5. TEMPAT SAMPAH
      权限.png
  6. TEMPAT SAMPAH
      模型.png
  7. TEMPAT SAMPAH
      测试api.png
  8. TEMPAT SAMPAH
      短信配置.png
  9. TEMPAT SAMPAH
      第三方登录.png
  10. TEMPAT SAMPAH
      组织.png
  11. TEMPAT SAMPAH
      证书.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. 部署服务和测试

TEMPAT SAMPAH
对象存储.png


TEMPAT SAMPAH
应用.png


TEMPAT SAMPAH
权限.png


TEMPAT SAMPAH
模型.png


TEMPAT SAMPAH
测试api.png


TEMPAT SAMPAH
短信配置.png


TEMPAT SAMPAH
第三方登录.png


TEMPAT SAMPAH
组织.png


TEMPAT SAMPAH
证书.png