Commit 1e47dcba authored by 李宇怀's avatar 李宇怀
Browse files

完成task F

parent 1a31c3a4
...@@ -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", "content-type", "authorization", "image/png", "image/jpeg", "AccessToken", "X-CSRF-Token", "Authorization", "Token"}, AllowHeaders: []string{"Origin", "Host", "User-Agent", "Content-Type", "Authorization", "X-CSRF-Token", "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,
......
...@@ -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("/getinfo", 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)
} }
......
...@@ -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")
}
...@@ -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
} }
......
...@@ -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,
......
...@@ -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()
}
}
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
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment