Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
李宇怀
Backend
Commits
1e47dcba
Commit
1e47dcba
authored
Sep 10, 2023
by
李宇怀
Browse files
完成task F
parent
1a31c3a4
Changes
7
Hide whitespace changes
Inline
Side-by-side
api/init.go
View file @
1e47dcba
...
@@ -36,7 +36,7 @@ func StartServer() error {
...
@@ -36,7 +36,7 @@ func StartServer() error {
e
.
Use
(
cors
.
New
(
cors
.
Config
{
e
.
Use
(
cors
.
New
(
cors
.
Config
{
AllowOrigins
:
[]
string
{
"http://localhost:8000"
,
"http://localhost:8080"
,
"http://localhost:63342"
},
AllowOrigins
:
[]
string
{
"http://localhost:8000"
,
"http://localhost:8080"
,
"http://localhost:63342"
},
AllowMethods
:
[]
string
{
"GET"
,
"POST"
,
"PUT"
,
"PATCH"
,
"DELETE"
,
"OPTIONS"
},
AllowMethods
:
[]
string
{
"GET"
,
"POST"
,
"PUT"
,
"PATCH"
,
"DELETE"
,
"OPTIONS"
},
AllowHeaders
:
[]
string
{
"Origin"
,
"Host"
,
"User-Agent"
,
"
c
ontent-
t
ype"
,
"
a
uthorization"
,
"
image/png"
,
"image/jpeg"
,
"AccessToken"
,
"X-CSRF-Token"
,
"Authorizatio
n"
,
"Token"
},
AllowHeaders
:
[]
string
{
"Origin"
,
"Host"
,
"User-Agent"
,
"
C
ontent-
T
ype"
,
"
A
uthorization"
,
"
X-CSRF-Toke
n"
,
"Token"
},
ExposeHeaders
:
[]
string
{
"Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type"
},
ExposeHeaders
:
[]
string
{
"Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type"
},
AllowCredentials
:
true
,
AllowCredentials
:
true
,
MaxAge
:
12
*
time
.
Hour
,
MaxAge
:
12
*
time
.
Hour
,
...
...
api/route/link.go
View file @
1e47dcba
...
@@ -16,8 +16,8 @@ func setupLinkController(r *gin.RouterGroup) {
...
@@ -16,8 +16,8 @@ func setupLinkController(r *gin.RouterGroup) {
p
:=
r
.
Group
(
"/link"
)
p
:=
r
.
Group
(
"/link"
)
p
.
POST
(
"/create"
,
lcw
.
Create
)
p
.
POST
(
"/create"
,
lcw
.
Create
)
p
.
POST
(
"/delete"
,
controller
.
ParseTokenMidware
(),
lcw
.
Delete
)
p
.
POST
(
"/delete"
,
controller
.
ParseTokenMidware
(),
lcw
.
Delete
)
p
.
GET
(
"/
get
info"
,
lcw
.
GetInfo
)
p
.
GET
(
"/info"
,
lcw
.
GetInfo
)
p
.
POST
(
"/
update
"
,
controller
.
ParseTokenMidware
(),
lcw
.
Update
)
p
.
POST
(
"/
info
"
,
controller
.
ParseTokenMidware
(),
lcw
.
Update
)
p
.
GET
(
"/getlist"
,
controller
.
ParseTokenMidware
(),
lcw
.
GetList
)
p
.
GET
(
"/getlist"
,
controller
.
ParseTokenMidware
(),
lcw
.
GetList
)
}
}
...
...
api/route/server.go
View file @
1e47dcba
...
@@ -14,7 +14,7 @@ func setupServerController(r *gin.RouterGroup) {
...
@@ -14,7 +14,7 @@ func setupServerController(r *gin.RouterGroup) {
// Implemented in controller package.
// Implemented in controller package.
}
}
r
.
GET
(
":short"
,
lcw
.
Link
)
r
.
GET
(
":short"
,
lcw
.
Link
)
r
.
GET
(
"/api/captcha/:target"
,
lcw
.
Veri
)
r
.
GET
(
"/api/captcha/:target"
,
lcw
.
CaptchaPic
)
}
}
type
ServerCtlWrapper
struct
{
//Wrapper类隔离接口具体逻辑
type
ServerCtlWrapper
struct
{
//Wrapper类隔离接口具体逻辑
...
@@ -50,3 +50,13 @@ func (w *ServerCtlWrapper) Veri(c *gin.Context) {
...
@@ -50,3 +50,13 @@ func (w *ServerCtlWrapper) Veri(c *gin.Context) {
}
}
dto
.
ResponseSuccess
(
c
,
"get verification server successfully"
)
dto
.
ResponseSuccess
(
c
,
"get verification server successfully"
)
}
}
// get verification
func
(
w
*
ServerCtlWrapper
)
CaptchaPic
(
c
*
gin
.
Context
)
{
err
:=
w
.
ctl
.
CaptchaPic
(
c
)
if
err
!=
nil
{
dto
.
ResponseFail
(
c
,
err
)
return
}
dto
.
ResponseSuccess
(
c
,
"get verification server successfully"
)
}
internal/controller/link.go
View file @
1e47dcba
...
@@ -97,15 +97,15 @@ func (c *LinkController) Delete(ctx *gin.Context, req *dto.LinkDeleteReq) error
...
@@ -97,15 +97,15 @@ func (c *LinkController) Delete(ctx *gin.Context, req *dto.LinkDeleteReq) error
logrus
.
Fatal
(
err
)
logrus
.
Fatal
(
err
)
return
err
return
err
}
}
var
link
model
.
Link
//
var link model.Link
err
=
dao
.
DB
(
ctx
)
.
Where
(
&
model
.
Link
{
Short
:
deleteLink
.
Short
})
.
First
(
&
link
)
.
Error
//
err = dao.DB(ctx).Where(&model.Link{Short: deleteLink.Short}).First(&link).Error
if
err
!=
nil
{
//
if err != nil {
if
err
==
gorm
.
ErrRecordNotFound
{
//
if err == gorm.ErrRecordNotFound {
logrus
.
Fatal
(
err
)
//
logrus.Fatal(err)
return
stacktrace
.
PropagateWithCode
(
err
,
dto
.
ErrNoShortLink
,
"ErrNoShortLink"
)
//
return stacktrace.PropagateWithCode(err, dto.ErrNoShortLink, "ErrNoShortLink")
}
//
}
return
err
//
return err
}
//
}
return
nil
return
nil
}
}
...
...
internal/controller/link_user_test.go
View file @
1e47dcba
...
@@ -143,14 +143,14 @@ func TestGetinfo(t *testing.T) {
...
@@ -143,14 +143,14 @@ func TestGetinfo(t *testing.T) {
{
{
userID
:
2
,
userID
:
2
,
input
:
dto
.
GetLinkInfoReq
{
input
:
dto
.
GetLinkInfoReq
{
Short
:
"
bing
"
,
Short
:
"
123
"
,
},
},
output
:
dto
.
GetLinkInfoResp
{
output
:
dto
.
GetLinkInfoResp
{
Active
:
null
.
BoolFrom
(
true
),
Active
:
null
.
BoolFrom
(
true
),
Comment
:
"
test link 2
"
,
Comment
:
"
bing
"
,
EndTime
:
null
.
NewTime
(
time
.
Date
(
2023
,
8
,
1
,
12
,
0
,
12
,
0
,
time
.
Local
),
true
),
EndTime
:
null
.
NewTime
(
time
.
Date
(
2023
,
8
,
1
,
12
,
0
,
12
,
0
,
time
.
Local
),
true
),
Origin
:
"https://
www
.bing.com"
,
Origin
:
"https://
cn
.bing.com"
,
Short
:
"
short1
"
,
//注意此处和bing不一样
Short
:
"
123
"
,
//注意此处和bing不一样
StartTime
:
null
.
NewTime
(
time
.
Date
(
2023
,
7
,
30
,
12
,
0
,
12
,
0
,
time
.
Local
),
true
),
StartTime
:
null
.
NewTime
(
time
.
Date
(
2023
,
7
,
30
,
12
,
0
,
12
,
0
,
time
.
Local
),
true
),
},
},
errorCode
:
0
,
errorCode
:
0
,
...
...
internal/controller/mid.go
View file @
1e47dcba
...
@@ -5,7 +5,6 @@ import (
...
@@ -5,7 +5,6 @@ import (
"go-svc-tpl/internal/dao"
"go-svc-tpl/internal/dao"
"go-svc-tpl/internal/dao/model"
"go-svc-tpl/internal/dao/model"
"net/http"
"net/http"
"strings"
"time"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go"
...
@@ -23,18 +22,22 @@ func ParseTokenMidware() gin.HandlerFunc {
...
@@ -23,18 +22,22 @@ func ParseTokenMidware() gin.HandlerFunc {
}
}
// validate token formate
// validate token formate
if
tokenString
==
""
||
!
strings
.
HasPrefix
(
tokenString
,
"Bearer "
)
{
if
tokenString
==
""
{
//|| !strings.HasPrefix(tokenString, "Bearer ") {
ctx
.
JSON
(
http
.
StatusUnauthorized
,
gin
.
H
{
"code"
:
401
,
"message"
:
"权限不足"
})
ctx
.
JSON
(
http
.
StatusUnauthorized
,
gin
.
H
{
"code"
:
401
,
"message"
:
"权限不足1"
,
"data"
:
tokenString
,
})
ctx
.
Abort
()
ctx
.
Abort
()
return
return
}
}
//提取token的有效部分("Bearer "共占7位)
//
//提取token的有效部分("Bearer "共占7位)
tokenString
=
tokenString
[
7
:
]
//
tokenString = tokenString[7:]
token
,
claims
,
err
:=
ParseToken
(
tokenString
)
token
,
claims
,
err
:=
ParseToken
(
tokenString
)
if
err
!=
nil
||
!
token
.
Valid
{
if
err
!=
nil
||
!
token
.
Valid
{
ctx
.
JSON
(
http
.
StatusUnauthorized
,
gin
.
H
{
"code"
:
401
,
"message"
:
"权限不足
"
})
ctx
.
JSON
(
http
.
StatusUnauthorized
,
gin
.
H
{
"code"
:
401
,
"message"
:
"权限不足
2"
,
"data"
:
tokenString
})
ctx
.
Abort
()
ctx
.
Abort
()
return
return
}
}
...
@@ -43,11 +46,12 @@ func ParseTokenMidware() gin.HandlerFunc {
...
@@ -43,11 +46,12 @@ func ParseTokenMidware() gin.HandlerFunc {
userId
:=
claims
.
UserId
userId
:=
claims
.
UserId
DB
:=
dao
.
DB
DB
:=
dao
.
DB
var
user
model
.
User
var
user
model
.
User
DB
(
ctx
)
.
Table
(
"User"
)
.
First
(
&
user
,
userId
)
DB
(
ctx
)
.
Table
(
"Users"
)
.
Where
(
&
model
.
User
{
ID
:
userId
})
.
First
(
&
user
)
// 用户不存在
// 用户不存在
if
user
.
ID
==
0
{
if
user
.
ID
==
0
{
ctx
.
JSON
(
http
.
StatusUnauthorized
,
gin
.
H
{
"code"
:
401
,
"message"
:
"权限不足
"
})
ctx
.
JSON
(
http
.
StatusUnauthorized
,
gin
.
H
{
"code"
:
401
,
"message"
:
"权限不足
用户不存在"
,
"data"
:
tokenString
})
ctx
.
Abort
()
ctx
.
Abort
()
return
return
}
}
...
@@ -121,3 +125,20 @@ func ParseToken(tokenString string) (*jwt.Token, *Claims, error) {
...
@@ -121,3 +125,20 @@ func ParseToken(tokenString string) (*jwt.Token, *Claims, error) {
})
})
return
token
,
claims
,
err
return
token
,
claims
,
err
}
}
func
corsset
()
gin
.
HandlerFunc
{
return
func
(
ctx
*
gin
.
Context
)
{
ctx
.
Writer
.
Header
()
.
Set
(
"Access-Control-Allow-Origin"
,
"*"
)
ctx
.
Writer
.
Header
()
.
Set
(
"Access-Control-Allow-Credentials"
,
"true"
)
ctx
.
Writer
.
Header
()
.
Set
(
"Access-Control-Allow-Headers"
,
"Content-Type,AccessToken,X-CSRF-Token, Authorization, Token"
)
ctx
.
Writer
.
Header
()
.
Set
(
"Access-Control-Allow-Methods"
,
"POST, GET, OPTIONS, PUT, PATCH, DELETE"
)
ctx
.
Writer
.
Header
()
.
Set
(
"Access-Control-Expose-Headers"
,
"Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type"
)
ctx
.
Writer
.
Header
()
.
Set
(
"Access-Control-Max-Age"
,
"172800"
)
ctx
.
Writer
.
Header
()
.
Set
(
"Access-Control-Allow-Credentials"
,
"true"
)
if
ctx
.
Request
.
Method
==
"OPTIONS"
{
ctx
.
AbortWithStatus
(
200
)
}
ctx
.
Next
()
}
}
internal/controller/server.go
View file @
1e47dcba
package
controller
package
controller
import
(
import
(
"bytes"
"fmt"
"go-svc-tpl/api/dto"
"go-svc-tpl/api/dto"
"go-svc-tpl/internal/dao"
"go-svc-tpl/internal/dao"
"go-svc-tpl/internal/dao/model"
"go-svc-tpl/internal/dao/model"
"net/http"
"net/http"
"path"
"strings"
"github.com/dchest/captcha"
"github.com/dchest/captcha"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
"gorm.io/gorm"
)
)
...
@@ -15,6 +20,7 @@ import (
...
@@ -15,6 +20,7 @@ import (
type
IServerController
interface
{
type
IServerController
interface
{
Link
(
*
gin
.
Context
,
*
dto
.
ServerLinkReq
)
error
Link
(
*
gin
.
Context
,
*
dto
.
ServerLinkReq
)
error
Veri
(
*
gin
.
Context
,
*
dto
.
ServerVeriReq
)
error
Veri
(
*
gin
.
Context
,
*
dto
.
ServerVeriReq
)
error
CaptchaPic
(
*
gin
.
Context
)
error
}
}
// >>>>>>>>>>>>>>>>>> Controller >>>>>>>>>>>>>>>>>
// >>>>>>>>>>>>>>>>>> Controller >>>>>>>>>>>>>>>>>
...
@@ -68,3 +74,55 @@ func (c *ServerController) Veri(ctx *gin.Context, req *dto.ServerVeriReq) error
...
@@ -68,3 +74,55 @@ func (c *ServerController) Veri(ctx *gin.Context, req *dto.ServerVeriReq) error
// 返回错误信息或nil
// 返回错误信息或nil
return
err
return
err
}
}
// 获取验证码图片
func
(
c
*
ServerController
)
CaptchaPic
(
ctx
*
gin
.
Context
)
error
{
imgName
:=
ctx
.
Param
(
"target"
)
logrus
.
Info
(
"GetCaptchaPng :"
+
imgName
)
ctx
.
Header
(
"Access-Control-Allow-Origin"
,
"http://localhost:8000, http://localhost:8080"
)
ctx
.
Header
(
"Access-Control-Allow-Credentials"
,
"true"
)
ctx
.
Header
(
"Access-Control-Allow-Headers"
,
"image/png, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With"
)
ServeHTTP
(
ctx
.
Writer
,
ctx
.
Request
,
imgName
)
return
nil
}
// 处理验证码图片请求
func
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
img
string
)
{
dir
,
_
:=
path
.
Split
(
r
.
URL
.
Path
)
id
:=
img
[
:
len
(
img
)
-
4
]
fmt
.
Println
(
"id :"
+
id
)
if
id
==
""
{
http
.
NotFound
(
w
,
r
)
return
}
fmt
.
Println
(
"reload :"
+
r
.
FormValue
(
"reload"
))
if
r
.
FormValue
(
"reload"
)
!=
""
{
captcha
.
Reload
(
id
)
}
lang
:=
strings
.
ToLower
(
r
.
FormValue
(
"lang"
))
download
:=
path
.
Base
(
dir
)
==
"download"
if
Serve
(
w
,
r
,
id
,
lang
,
download
,
90
,
50
)
==
captcha
.
ErrNotFound
{
http
.
NotFound
(
w
,
r
)
return
}
}
// 编辑响应头,显示验证码图片
func
Serve
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
id
,
lang
string
,
download
bool
,
width
,
height
int
)
error
{
w
.
Header
()
.
Set
(
"Cache-Control"
,
"no-cache,no-store,must-revalidate"
)
w
.
Header
()
.
Set
(
"Pragma"
,
"no-cache"
)
w
.
Header
()
.
Set
(
"Expires"
,
"0"
)
w
.
Header
()
.
Set
(
"Content-Type"
,
"image/png"
)
var
content
bytes
.
Buffer
captcha
.
WriteImage
(
&
content
,
id
,
width
,
height
)
if
download
{
w
.
Header
()
.
Set
(
"Content-Type"
,
"application/octet-stream"
)
}
w
.
Header
()
.
Set
(
"Access-Control-Allow-Origin"
,
"Content-Type, image/png"
)
//显示验证码图片
w
.
Write
(
content
.
Bytes
())
return
nil
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment