diff --git a/_posts/API_software/2023-07-29-github.md b/_posts/API_software/2023-07-29-github.md index 7a83a09..3757757 100644 --- a/_posts/API_software/2023-07-29-github.md +++ b/_posts/API_software/2023-07-29-github.md @@ -14,7 +14,7 @@ tags: {:toc} -### 1 github使用指南 + @@ -25,13 +25,17 @@ tags: 版本控制是什么? -一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统 + +- 一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统 为什么需要版本控制? -更好的关注变更,了解到每个版本的改动是什么,方便对改动的代码进行检查,预防事故发生也能够随时切换到不同的版本,回滚误删误改的问题代码; + +- 更好的关注变更,了解到每个版本的改动是什么,方便对改动的代码进行检查,预防事故发生也能够随时切换到不同的版本,回滚误删误改的问题代码; +什么是 git + - Git 是一款免费、开源的分布式版本控制系统,他是著名的 Linux 发明者 Linus Torvalds 开发的 - GitHub 主要提供基于 git 的**版本托管**服务。也就是说现在 GitHub 上托管的所有项目代码都是基于 Git 来进行版本控制的,所以 Git 只是 GitHub 上用来管理项目的一个工具而已,GitHub 的功能可远不止于此! @@ -86,6 +90,12 @@ Gist + + + + + + #### 1.2 git 目录结构 - Git 的本质是一个**文件系统**,工作目录中的所有文件的**历史版本**以及**提交记录**(commit)都是以文件对象的方式保存在 `.git` 目录中的。 @@ -176,13 +186,26 @@ git remote add origin 仓库名 -#### 远端仓库/ remote + Git 有三种状态,你的文件可能处于其中之一: 已提交(committed)、已修改(modified) 和 已暂存(staged)。 + +- 已修改表示**修改**了文件,但还没保存到数据库中。 +- 已暂存表示对一个已修改文件的当前版本做了标记,使之包含在下次提交的快照中。 +- 已提交表示数据已经安全地保存在本地数据库中。 + + + + + +### 2 远端仓库/ remote + +#### 2.1 http 和 git 协议有什么区别 - 第一组使用 HTTPS 协议,第二组使用 SSH 协议。具体选择哪种协议取决于你的需求和配置。 - 使用 HTTPS 协议需要提供**用户名和密码**,而使用 SSH 协议则需要设置密钥对。 ```bash -以下两者有什么区别 git remote -v +# 用于查看当前项目中配置的所有远程仓库的详细信息。 +git remote -v origin https://github.com/*****/tinywebserver (fetch) origin https://github.com/*****/tinywebserver (push) @@ -190,17 +213,18 @@ origin git@github.com:*****/simple-douyin.git (fetch) origin git@github.com:*****/simple-douyin.git (push) ``` +其中 +- `fetch`:`git fetch` 命令用于从远程仓库获取最新的代码和提交历史,但不会自动合并或更新你的本地分支。它将远程仓库的内容下载到你的本地仓库,使你能够查看和**比较**远程分支与本地分支之间的差异。`fetch` 操作**不会修改**你的本地分支,只会更新你的本地仓库。 +- `push`:`git push` 命令用于将你的本地分支的提交推送到远程仓库。它将你的本地分支的提交上传到远程仓库,并将远程仓库的相应分支更新为你的提交。`push` 操作会修改远程仓库的内容。 -1. `fetch`:`git fetch` 命令用于从远程仓库获取最新的代码和提交历史,但不会自动合并或更新你的本地分支。它将远程仓库的内容下载到你的本地仓库,使你能够查看和**比较**远程分支与本地分支之间的差异。`fetch` 操作**不会修改**你的本地分支,只会更新你的本地仓库。 -2. `push`:`git push` 命令用于将你的本地分支的提交推送到远程仓库。它将你的本地分支的提交上传到远程仓库,并将远程仓库的相应分支更新为你的提交。`push` 操作会修改远程仓库的内容。 -```bash -# 用于查看当前项目中配置的所有远程仓库的详细信息。 -git remote -v -git remote add origin_ssh git@github.com: git/git.git -git remote add origin_http https://github. com/git/git.git +#### 2.2 链接远程仓库 + +```bash +# 链接远程仓库,使通过网络与远程仓库进行交互。 +git remote add # 设置fetch 和 push 为不同的仓库 git remote set-url --add --push origin git@github. com: my_repo/git.git @@ -210,6 +234,8 @@ git remote set-url --add --push origin git@github. com: my_repo/git.git + + #### 查看文件内容 `git cat-file` 是一个用于查看 Git 对象内容的命令。Git 中的对象是存储在仓库中的基本数据单元,包括提交(commit)、树(tree)、标签(tag)和文件内容(blob)等。 @@ -238,7 +264,9 @@ git remote set-url --add --push origin git@github. com: my_repo/git.git -#### 分支操作 +### 3 分支操作 + +#### 3.1 本地操作分支 ```bash # 查看本地分支列表 @@ -249,24 +277,21 @@ git branch -r # 新建一个叫 develop 的分支 git branch develop +# 创建一个名为 "test" 的新分支,并从 "master" 分支进行分叉。 +git branch test master + # 切换 到 dev 分支 git checkout dev +# 新建并且自动切换到 develop 分支 +git checkout -b dev + # 删除本地分支 git branch -d develop -# 删除远程分支 -git push origin :develop -# 新建并且自动切换到 develop 分支 -git checkout -b dev -# 把 develop 分支推送到远程仓库 -git push origin develop - -# 如果你远程的分支想取名叫 develop2 ,那执行以下代码: -git push origin develop:develop2 #用来切换tag git checkout v1.0 @@ -282,7 +307,60 @@ git tag v0.0.1 -合并分支 + + +#### 3.2 想拉取远程仓库的 dev 分支怎么做 + +要拉取远程仓库的 dev 分支,可以按照以下步骤进行操作: + +```bash +git fetch origin dev +``` + + + +1. 使用 git fetch origin dev 命令从远程仓库拉取 dev 分支的最新代码。这将会将远程仓库的 dev 分支代码下载到你本地仓库,不会自动合并到你当前的分支。 +2. 使用 git checkout dev 命令切换到 dev 分支。如果本地还没有 dev 分支,可以使用 git checkout -b dev origin/dev 命令创建并切换到 dev 分支。 + +现在你已经成功拉取了远程仓库的 dev 分支,可以开始在本地与该分支进行开发和修改。记得在操作前先保存好本地的修改,以免冲突。 + + + + + +#### 3.3 远程分支 + +- 远程分支**没有新建**指令, 直接 **push** 就好 + +```bash +# 删除远程分支 +git push origin --delete publish +# 通过将 设置为空,就表示没有要推送的本地分支,而只是请求删除远程分支 +git push origin :develop + +# 如果你远程的分支想取名叫 develop2 ,那执行以下代码: +git push origin develop:develop2 + +# 把 develop 分支推送到远程仓库 +git push origin develop +``` + + + + + + + +#### 3.4 合并分支 + +- Git 保存的不是文件的变化或者差异,而是一系列不同时刻的 **快照** 。在进行提交操作时,Git 会保存一个提交对象(commit object)。 +- Git 的分支,其实本质上仅仅是指向**提交对象**的可变**指针**。 +- Git 又是怎么知道当前在哪一个分支上呢? 也很简单,它有一个名为 HEAD 的特殊指针。指向当前所在的本地分支(译注:将 HEAD 想象为当前分支的别名)。 +- 由于 Git 的分支实质上仅是包含所指对象校验和(长度为 40 的 SHA-1 值字符串)的文件,所以它的创建和销毁都异常高效。 + + + + ```bash # 我们在一个 featureA 分支开发完了一个功能,这个时候需要合并到主分支 master 上去 @@ -302,6 +380,134 @@ git rebase featureA + + +#### 3.5 遇到冲突时的分支合并 + +- 有时候合并操作不会如此顺利。 如果你在两个不同的分支中,对**同一个文件**的同一个部分进行了不同的修改,Git 就没法干净的合并它们。 +- 此时 Git 做了合并,但是**没有自动地创建一个新的合并提交**。 Git 会**暂停**下来,等待你去**解决**合并产生的**冲突**。 + + + +```bash +# 现在在 master分支, 想要合并 dev 的内容 +$ git merge dev +Auto-merging index.html +CONFLICT (content): Merge conflict in index.html +Automatic merge failed; fix conflicts and then commit the result. + +$ git status +On branch master +You have unmerged paths. + (fix conflicts and run "git commit") +Unmerged paths: + (use "git add ..." to mark resolution) + both modified: index.html +no changes added to commit (use "git add" and/or "git commit -a") +``` + + + +任何因包含合并冲突而有待解决的文件,都会以未合并状态标识出来。 Git 会在有冲突的文件中加入标准的冲突 +解决标记,这样你可以打开这些包含冲突的文件然后手动解决冲突。 出现冲突的文件会包含一些特殊区段,看 +起来像下面这个样子: + +```bash +# HEAD 所指向的版本 +<<<<<<< HEAD:index.html + +======= +# 合并所指向的版本 + +>>>>>>> iss53:index.html +``` + +为了解决冲突,你必须选择使用由 ======= 分割的两部分中的一个,或者你也可以自行合并这些内 +容。同时 `<<<<<<<` ,` =======` , 和 `>>>>>>>` 这些行被**完全删除**了。 + + + + + +#### 3.6 多人合作冲突 + +远程跟踪分支是远程分支状态的引用。它们是你无法移动的本地引用。一旦你进行了网络通信, Git 就会为你移 +动它们以精确反映远程仓库的状态。它们以\/\ 的形式命名。 + +假设你的网络里有一个在 `git.ourcompany.com 的 Git` 服务器。 如果你从这里克隆,Git 的 clone 命令会为你自动将其命名为 origin,拉取它的所有数据, 创建一个指向它的 `master `分支的指针,并且在本地将其命名为 `origin/master`。Git 也会给你一个与 origin 的master 分支在指向同一个地方的本地 master 分支,这样你就有工作的基础。 + + + +隔离性 + +- 如果你在本地的 master 分支做了一些工作,在同一段时间内有其他人推送**提交**到 `git.ourcompany.com` 并且**更新**了它的 master 分支,这就是说你们的提交历史已走向不同的方向。 即便这样,只要你保持不与origin 服务器连接(并拉取数据),你的 origin/master 指针就不会移动。 +- 如果要与给定的远程仓库**同步数据**,运行 `git fetch `命令 + + + + + + + + + + + + + + + +### 常见开发场景 + +#### 1、本地仓库有文件,远程服务器上面是新建的仓库 + +```bash +# 1 初始化仓库 +git init test + +# 2 在仓库中新建文件编辑内容(例如test.txt) + +# 3 添加到暂存区 +git add test.txt + +# 提交修改 +git commit test.txt -m '提交test.txt' + +# 关联远程仓库, origin也是默认仓库的名字,也可以命名为其它的名字 + git remote add origin git@gitee.com:blueses/test.git + +# 把本地仓库的master分支与远程仓库的master分支关联起来 +# 把本地仓库的master分支的文件推送到远程仓库的master分支中 + git push -u origin master + + +``` + + + + + +#### 2、远程服务器上面有很多代码,要拉取到本地开始开发 + +```bash +# 直接克隆 + git clone git@gitee.com:blueses/test.git + +# add、commit、pull、push 三步走 +``` + + + + + + + + + +### 其他操作 + #### 提交操作 ```bash @@ -328,7 +534,7 @@ filter --branch ```bash git reflog expire --expire=now --all - git gc --prune=now +git gc --prune=now ``` @@ -336,7 +542,7 @@ git reflog expire --expire=now --all -#### 拉取操作 +#### 拉取操作概念辨析 - `Clone`拉取完整的仓库到本地目录,可以指定分支,深度. - `Fetch`将远端某些分支最新代码拉取到本地,不会执行merge操作,会修改refs/remote内的分支信息,如果需要和本地代码合并需要手动操作. diff --git a/_posts/byte_tech/2023-07-25-go-1.md b/_posts/byte_tech/2023-07-25-go-1.md index 8344fd2..e92fd4d 100644 --- a/_posts/byte_tech/2023-07-25-go-1.md +++ b/_posts/byte_tech/2023-07-25-go-1.md @@ -1091,6 +1091,10 @@ cd $GOPATH #### go module +有了 Go module 之后,可以方便地管理项目的依赖关系,并且**不需要手动**下载库。使用 Go module,你可以在代码中引入需要的库,并通过指定版本或者版本范围来自动获取相应的库。当你首次引入一个新的库时,Go module 会自动下载该库及其依赖到本地的缓存中。这样,你就可以随意引入库,而无需手动下载。 + + + 依赖管理三要素 - 1.配置文件, 描述依赖go.mod diff --git a/_posts/byte_tech/2023-08-12-project.md b/_posts/byte_tech/2023-08-12-project.md index 2416c90..6d4a113 100644 --- a/_posts/byte_tech/2023-08-12-project.md +++ b/_posts/byte_tech/2023-08-12-project.md @@ -16,6 +16,151 @@ tags: +### 我的工作---发布视频 + + + +#### 简介 + +我的工作为发布视频, 将这个任务分解为几个小任务, 先看哪些任务能够自己独立完成,先完成这些任务, 之后再根据小组成员的接口, 实现完整的功能 + + + +环境 + +- 需要提前安装`ffmpeg` + + + + + +发布视频的流程 + +- 鉴权 ----- 使用别人的接口 +- 存储视频 ---- ( demo中 有 ) +- 抽取封面并存储 +- 视频 和 封面 上传到 `cdn` ( 没有, 因此没有做 ) +- 将收到的视频信息( 视频名称, 用户名, 播放地址, 封面的地址 )存储到数据库中 ---- 使用数据库的接口 +- 返回消息 ( 发布成功) + + + +因此最先做的工作就是 + +- 确定资源**存储的位置**, 通过查找**路由**得知, 有这样一个映射`r.Static("/static", "./public")`, 我们访问静态资源的时候, 网址为`xxx/static/fileName.txt`, 通过` c.Request.Host`字段, 来获得域名 : `2f781ee3592dd7a9ff0bbd0007fe40ce-app.1024paas.com`, 加头(协议)加尾(路径 + 文件名), 进行字符串拼接 +- 使用`ffmpeg`来抽取某一帧来做封面, 需要设置 其 **环境** + + + + + +```go +// controller/ publish.go +// 没有其他合作者的提供的接口 +func Publish(c *gin.Context) { + // token, 鉴权 + + // 存储 + err := c.SaveUploadedFile(data, saveFile); + + // 抽取并存储图片 + Vedio2Jpeg(saveFile, 6) + + // 拼接网址 + vedio_url := "https://"+ domain + "/static/"+ finalName + + // 放入数据库 + db.creat()..... + +} + + + +``` + + + +抽取图片 demo + +```go +// 将视频抽取一帧, 转化为流 +package examples + +import ( + "bytes" + "fmt" + "io" + "os" + + ffmpeg "github.com/u2takey/ffmpeg-go" +) + +func ExampleReadFrameAsJpeg(inFileName string, frameNum int) io.Reader { + buf := bytes.NewBuffer(nil) + err := ffmpeg.Input(inFileName). + Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%d)", frameNum)}). + Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg"}). + WithOutput(buf, os.Stdout). + Run() + if err != nil { + panic(err) + } + return buf +} +``` + + + +#### 队友的接口 + +```go +// 鉴权接口 +// 参数: token, 返回: username +func ParseToken(token string) (string, error) + + +// 数据库接口---用户 +func (*UserDao) FindUserByName(username string) (*User, error) +func (d *UserDao) FindUserById(id int64) (*User, error) +_, err := models.NewUserDaoInstance().FindUserByName("qong"); + +// 数据库接口--- 视频 +func (*VideoDao) CreateVideo(video *Video) (*Video, error) + +``` + + + + + +#### 使用了接口之后的伪代码 + +```go +func Publish(c *gin.Context) { + // token, 鉴权 + token := c.PostForm("token") + user_name, err := ParseToken(token); + user, err := models.NewUserDaoInstance().FindUserByName(user_name) + var user_id = user.UserId + + // 存储 + err := c.SaveUploadedFile(data, saveFile); + + // 抽取并存储图片 + Vedio2Jpeg(saveFile, 6) + + // 拼接网址 + vedio_url := "https://"+ domain + "/static/"+ finalName + + // 放入数据库 + video1 := models.Video{UserId : user_id, PlayUrl : vedio_url, CoverUrl : img_url , } + _, err = models.NewVideoDaoInstance().CreateVideo(&video1) + +} +``` + + + @@ -75,10 +220,7 @@ var chatConnMap = sync.Map{} func RunMessageServer() { listen, err := net.Listen("tcp", "127.0.0.1:9090") - if err != nil { - fmt.Printf("Run message sever failed: %v\n", err) - return - } + for { conn, err := listen.Accept() @@ -236,12 +378,14 @@ func (c *gin.Context) JSON(code int, obj interface{}) -### GORM +### GORM 使用 + +[go 语言 gorm 基本使用_go gorm_含光君~的博客 - CSDN 博客](https://blog.csdn.net/yoyogu/article/details/109318626) #### 定义数据类型 ```go -// 定义类型 +// 内部定义类型, 直接引用就好 type Model struct { ID uint `gorm:"primaryKey"` CreatedAt time.Time @@ -251,7 +395,8 @@ type Model struct { // 对于匿名字段,GORM 会将其字段包含到其父结构中 -type User struct { +// 表名默认是模型的复数形式,列名默认是字段名的驼峰形式 +type User struct { // 默认表名是`users` gorm.Model Name string } @@ -278,6 +423,7 @@ import ( func main() { // refer https://github.com/go-sql-driver/mysql#dsn-data-source-name for details dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" + // 创建了一个新的 gorm.Config 对象,并将其作为参数传递给 Open 函数 db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) } ``` @@ -286,7 +432,7 @@ func main() { - +使用环境变量连接数据库 ```go package main @@ -349,11 +495,74 @@ func getConnectionString() string { ) ``` +**** + + + +#### 创建 + +```go +user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()} + +result := db.Create(&user) // pass pointer of data to Create + +// 批量处理数据 +users := []*User{ + User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}, + User{Name: "Jackson", Age: 19, Birthday: time.Now()}, +} + +result := db.Create(users) // pass a slice to insert multiple row + +result.Error // returns error +result.RowsAffected // returns inserted records count +``` + + + +#### 简单查询 + +```go +// 获取第一条记录,按主键排序 +db.First(&user); +select * from users order by id limit 1; +// 获取最后一条记录,按主键排序 +db.Last(&user); +select * from users order by id desc limit 1; +// 获取所有记录 +db.Find(&user); +select * from users; +// 使用主键获取记录 +// select * from users where id =10; +db.First(&user,10); + + +``` + + + + + +#### select 语句 + +```go +// select name,age from users; +db.Select("name","age").Find(&user); + + +db.Select([]string{"name","age"}).Find(&user); + +db.Table("users").Select("COALESCE(age,?)", 42).Rows() +SELECT COALESCE(age,'42') FROM users; +``` + + +### 其他库 #### 抽取图片 diff --git a/_posts/byte_tech/2023-08-18-hole.md b/_posts/byte_tech/2023-08-18-hole.md new file mode 100644 index 0000000..e1c172e --- /dev/null +++ b/_posts/byte_tech/2023-08-18-hole.md @@ -0,0 +1,144 @@ +--- +layout: blog +banana: true +category: byte_tech +title: "漏洞" +date: 2023-08-18 12:59:58 +background: green +tags: +- byte_tech +- go +--- + +* content +{:toc} + + + + + + + + + + +### 服务端漏洞 + + + +#### 安全事件 + +- 数据泄漏 +- 服务瘫痪 +- 成果失窃 +- 系统劫持 + + + + + +#### SQL注入 + +SQL语句静态模板和动态数据部分没有严格区分,如果在数据项中加入了某些SOL语句关键字(比如说SELECT、DROP等等),这些SQL语句就很可以在数据库写入或读取数据时得到**执行**. + + + +防护方式: + +- 1.尽量不要基于DB的Raw方法拼接构造SQL语句,而应该使用预编译、ORM框架 +- 2.使用ORM框架时,应该注意框架中的特性,可能存在不安全的写法导致的SQL注入问题. +- 3.在复杂场景一定要使用拼接SQL,需要对外部输入进行**转义**. + + + +#### 命令执行 + +代码中遇到需要调用某个命令才能完成的功能时候, 会涉及到命令拼接, 如果命令拼接没有做好安全过滤, 那么将会导致命令注入风险, 服务器权限将会被控制 + +防护方式: + +- 1.对动态的值尽可能设置白名单进行验证. +- 2.如果某些位置无法白名单,需要尝试对数据类型进行校验. +- 3.特殊字符黑名单的过滤,或者转义. + + + + + +#### 越权漏洞 + +- 未授权 +- 水平越权 +- 垂直越权 + + + + + +#### SSRF + +SSRF又称服务端请求伪造攻击,指攻击者利用后端服务器为跳板,让后端服务向非预期网络地址(主要指内网地址)发出恶意请求,获取敏感信息或执行恶意操作. + +实例: 设置头像, 输入一个网址 + + + + + +#### 文件上传漏洞 + +防护方案: + +- 1.限制文件类型:如果系统只需要图片类型, 可以从服务端解析文件格式, 限制只能传入特定的文件格式. +- 2.站库分离:应用部署的位置和上传的文件分离, 一般可以使用TOS、OSS等进行文件存储. +- 3.防止图床:对图片访问链接进行限制,包括时间限制, 访问身份限制等. + + + + + + + +### 客户端漏洞 + +#### 开放重定向 + +开放重定向: 某些需要重定向到其他站点的功能, 往往在参数中携带需要重定向的URL, 但实际程序逻辑没有控制好重定向的范围, 导致攻击者可以构造恶意链接, 诱导用户重定向到恶意站点. + +危害:钓鱼攻击. +修复方案:对重定向严格进行白名单控制并正确校验匹配白名单. + + + + + +#### XSS + +防护方法: + +- 1.输入过滤:对输入的特殊字符进行拦截,禁止前端提交**特殊字符** +- 2.输出过滤: + a.当字符输出到Dom时候,对危险字符进行html encode,避免XSS. + b.使用vue/react等框架时候,避免使用危险指令,而应该使用安全指令.v-html/v-text +- 3.富文本场景:比如文章发布场景,本身是需要提供富文本功能,这时候需要严格限制tag和attribute,可以在代码层面做白名单或者黑名单. + +- 4.CSP:用于缓解XSS,理念是对当前站点允许加载什么源的资源、发送什么请求能进行限制. + + + + + + + +#### CSRF + +跨站请求伪造(CSRF): 允许攻击者诱导用户访问恶意链接,执行用户非预期执行的操作. +危害: 用户执行敏感操作,如关注其他用户,或者更改账号的安全邮箱等. + +防护方式: 防护的**核心**是判断请求的来源 + +- CSRF tokens: **首次**访问时候给客户端传递一个token, 客户端每次访问时候都**必须带上**此 token 才能访问. +- SameSite cookies: Strick -> Lax(Default) -> None.核心是禁止某些场景发送第三方cookie. +- Referer-based validation:校验 Referer来源是否是合法站点. + 思考:大厂微服务场景,CSRF防护应该怎么做? + diff --git a/assets/git_proGit.pdf b/assets/git_proGit.pdf new file mode 100644 index 0000000..cb2fb2b Binary files /dev/null and b/assets/git_proGit.pdf differ diff --git a/assets/style_cpp_google.pdf b/assets/style_cpp_google.pdf new file mode 100644 index 0000000..87ec9a7 Binary files /dev/null and b/assets/style_cpp_google.pdf differ