作者 yangfu

增加过滤器 验证 sign access_toke uuid

... ... @@ -5,6 +5,8 @@ runmode = dev
#没设置的话 this.Ctx.Input.RequestBody 没有值
copyrequestbody = true
#enablexsrf = true
#开启应用内文档开关
EnableDocs = true
... ...
package controllers
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"github.com/astaxie/beego"
"github.com/astaxie/beego/context"
"github.com/astaxie/beego/validation"
"gitlab.fjmaimaimai.com/mmm-go/ability/protocol"
"gitlab.fjmaimaimai.com/mmm-go/ability/services/auth"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/common"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/mybeego"
"strconv"
//"strconv"
"strings"
)
type BaseController struct {
mybeego.BaseController
}
var DefaultController *BaseController = &BaseController{}
//Valid valid struct
func (this *BaseController)Valid(obj interface{})(result bool ,msg *mybeego.Message){
/*校验*/
... ... @@ -47,4 +58,105 @@ func (this *BaseController)GenMessage(rsp interface{},err error)*mybeego.Message
}
msg = mybeego.NewMessage(1)
return msg
}
func GetRequestHeader(ctx *context.Context)*protocol.RequestHeader{
h :=&protocol.RequestHeader{}
h.AccessToken = ctx.Input.Header("x-mmm-accesstoken")
h.AppProject = ctx.Input.Header("x-mmm-appproject")
h.DeviceType = ctx.Input.Header("x-mmm-devicetype")
h.Sign = ctx.Input.Header("x-mmm-sign")
h.Uuid = ctx.Input.Header("x-mmm-uuid")
h.TimeStamp = ctx.Input.Header("x-mmm-timestamp")
h.Uid,_=strconv.ParseInt(ctx.Input.Header("uid"),10,64)//需要uid写入到header里面
return h
}
func FilterComm(ctx *context.Context){
if strings.HasSuffix(ctx.Request.RequestURI,"login"){
return
}
if beego.BConfig.RunMode!="prod"{
return
}
//1.检查签名
if !CheckSign(ctx){
return
}
//2.检查token是否有效
if !CheckToken(ctx){
return
}
//3.查重uuid
if !CheckUuid(ctx){
return
}
return
}
//检查签名
func CheckSign(ctx *context.Context)(result bool){
var(
h *protocol.RequestHeader
sign string
signHex string
)
result = true
h =GetRequestHeader(ctx)
//1.检查签名
sign =fmt.Sprintf("v!(MmM%v%v%vMmM)i^",h.TimeStamp,h.Uuid,h.AccessToken)
sha256:=sha256.New()
sha256.Write([]byte(sign))
signHex = hex.EncodeToString(sha256.Sum(nil))
if strings.Compare(signHex,h.Sign)!=0{
msg :=mybeego.NewMessage(113)
log.Error(fmt.Sprintf("%v req:%v resp:%v %v",ctx.Request.RequestURI,common.AssertJson(h),common.AssertJson(msg),signHex))
ctx.Output.JSON(msg, false, false)
result =false
return
}
return
}
//检查access_token
func CheckToken(ctx *context.Context)(result bool){
var (
msg *mybeego.Message
)
result = true
defer func(){
if msg!=nil{
result =false
ctx.Output.JSON(msg,false,false)
}
}()
token := ctx.Input.Header("x-mmm-accesstoken")
if rsp,err:=auth.CheckToken(&protocol.CheckTokenRequest{Token:token});(err!=nil || rsp.UserInfo==nil){
msg = DefaultController.GenMessage(rsp,err)
log.Error(fmt.Sprintf("%v req:%v resp:%v",ctx.Request.RequestURI,token,common.AssertJson(msg)))
return
}else{
if rsp.UserInfo!=nil{
//设置附加数据
ctx.Request.Header.Add("uid",fmt.Sprintf("%v",rsp.UserInfo.Uuid))
}
}
return
}
//检查Uuid
func CheckUuid(ctx *context.Context)(result bool){
var (
msg *mybeego.Message
)
result = true
defer func(){
if msg!=nil{
result =false
ctx.Output.JSON(msg,false,false)
}
}()
uuid := ctx.Input.Header("x-mmm-uuid")
msg = DefaultController.GenMessage(auth.CheckUuid(&protocol.CheckUuidRequest{Uuid:uuid}))
if msg!=nil{
log.Error(fmt.Sprintf("%v req:%v resp:%v",ctx.Request.RequestURI,uuid,common.AssertJson(msg)))
}
return
}
\ No newline at end of file
... ...
... ... @@ -3,6 +3,7 @@ package main
import (
"github.com/astaxie/beego"
_ "github.com/go-sql-driver/mysql"
"gitlab.fjmaimaimai.com/mmm-go/ability/controllers"
"gitlab.fjmaimaimai.com/mmm-go/ability/protocol"
_ "gitlab.fjmaimaimai.com/mmm-go/ability/routers"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/config"
... ... @@ -32,6 +33,7 @@ func main() {
defer func(){
log.Info("app on stop!")
}()
beego.InsertFilter("/*",beego.BeforeRouter,controllers.FilterComm)
protocol.InitMessageCode()
log.Info("app on start!")
log.Info("Beego Run Mode:",beego.BConfig.RunMode)
... ...
... ... @@ -10,7 +10,7 @@ import (
)
type LogUuid struct {
Id int `orm:"column(id);auto" description:"主键ID"`
Id int64 `orm:"column(id);auto" description:"主键ID"`
Uuid string `orm:"column(uuid);size(128)"`
}
... ... @@ -32,7 +32,7 @@ func AddLogUuid(m *LogUuid) (id int64, err error) {
// GetLogUuidById retrieves LogUuid by Id. Returns error if
// Id doesn't exist
func GetLogUuidById(id int) (v *LogUuid, err error) {
func GetLogUuidById(id int64) (v *LogUuid, err error) {
o := orm.NewOrm()
v = &LogUuid{Id: id}
if err = o.Read(v); err == nil {
... ... @@ -136,7 +136,7 @@ func UpdateLogUuidById(m *LogUuid) (err error) {
// DeleteLogUuid deletes LogUuid by Id and returns error if
// the record to be deleted doesn't exist
func DeleteLogUuid(id int) (err error) {
func DeleteLogUuid(id int64) (err error) {
o := orm.NewOrm()
v := LogUuid{Id: id}
// ascertain id exists in the database
... ... @@ -148,3 +148,12 @@ func DeleteLogUuid(id int) (err error) {
}
return
}
func GetLogUuidByUuid(uuid string)(v *LogUuid, err error) {
o := orm.NewOrm()
sql :="select * from log_uuid where uuid=?"
if err = o.Raw(sql,uuid).QueryRow(&v); err == nil {
return v, nil
}
return nil, err
}
... ...
... ... @@ -208,3 +208,12 @@ func GetUserInfoByClientId(clintId string)(v *UserInfo, err error) {
return nil, err
}
func GetUserInfoByToken(token string)(v *UserInfo, err error) {
o := orm.NewOrm()
sql :="select * from user_info where access_token=? and access_exp >= Now() and enabled = 1"
if err = o.Raw(sql,token).QueryRow(&v); err == nil {
return v, nil
}
return nil, err
}
... ...
package protocol
import "gitlab.fjmaimaimai.com/mmm-go/ability/models"
const (
LoginPassPord ="signInPassword"
LoginSmdcode ="signInCaptcha"
)
type RequestHeader struct {
TimeStamp string
Uuid string
Sign string
DeviceType string
AppProject string
AccessToken string
Uid int64
}
/*Login */
type LoginRequest struct {
Phone string `json:"phone" valid:"Required;Mobile"`
... ... @@ -63,3 +75,20 @@ type Access struct {
RefreshToken string
}
/*CheckToken */
type CheckTokenRequest struct {
Token string
}
type CheckTokenResponse struct {
IsValid bool //true:过期 false:没有过期
UserInfo *models.UserInfo
}
/*CheckUuid */
type CheckUuidRequest struct {
Uuid string
}
type CheckUuidResponse struct {
}
... ...
... ... @@ -101,4 +101,40 @@ func RefreshToken(request *protocol.RefreshTokenRequest)(rsp *protocol.RefreshTo
//loginType mobile im
func refreshToken(uid int64,loginType string)(rsp *protocol.Access,err error){
return nil,nil
}
func CheckToken(request *protocol.CheckTokenRequest)(rsp *protocol.CheckTokenResponse,err error){
var (
userInfo *models.UserInfo
)
if len(request.Token)==0{
err = common.NewErrorWithMsg(4141,"token not empty")
return
}
userInfo,err =models.GetUserInfoByToken(request.Token)
if err!=nil{
err =common.NewError(4141,err)
return
}
rsp =&protocol.CheckTokenResponse{
UserInfo:userInfo,
IsValid:true,
}
return
}
func CheckUuid(request *protocol.CheckUuidRequest)(rsp *protocol.CheckUuidResponse,err error){
var (
logUuid *models.LogUuid
)
if len(request.Uuid)==0{
err = common.NewErrorWithMsg(4142,"uuid not empty")
}
logUuid,err=models.GetLogUuidByUuid(request.Uuid)
if err==nil && logUuid!=nil{
err = common.NewErrorWithMsg(4142,"uuid not empty")
}
models.AddLogUuid(&models.LogUuid{Uuid:request.Uuid})
rsp =&protocol.CheckUuidResponse{}
return
}
\ No newline at end of file
... ...