golang gin框架oauth2 四种保存token方法

原创
2022/05/18 16:16
阅读数 866

golang gin框架oauth2 四种保存token方法

1.其它信息请参考项目

golang gin 框架实现 oauth2

2.增加4个配置文件通过viper读取配置

在根目录增加conf文件夹,添加如下文件 server.yml

server:
  port: 9096

oauth.yml

oauth:
  accessTokenExp: 200  #hour
  refreshTokenExp: 200
  isGenerateRefresh: 1  # 1 or 0 是否创建
  tokenStore: file  # mongo  redis  memory file

mongo.yml

mongo:
  host: ip
  port: 27017
  user: user
  pass: 123456
  dbName: test

redis.yml

redis:
  host: ip
  port: 6379
  pass: pass
  db: 15

3.调整main方法

package main

import "logistics/server"

func main() {
	server.Start()
}

4.增加server.go文件

通过viper读取配置文件 work, _ := os.Getwd() viper.SetConfigName("server") viper.SetConfigType("yml") viper.AddConfigPath(work + "/conf") viper.ReadInConfig() viper.GetString("server.port")

package server

import (
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"logistics/demo"
	"logistics/oauth2"
	"os"
)

func Start(){
	work, _ := os.Getwd()
	viper.SetConfigName("server")
	viper.SetConfigType("yml")
	viper.AddConfigPath(work + "/conf")
	viper.ReadInConfig()
	g := gin.Default()
	auth := g.Group("/auth")
	{
		auth.GET("/token", oauth2.TokenRequest)
		auth.GET("/credentials",oauth2.Credentials)
	}
	de := g.Group("/demo")
	{
		de.GET("/message",demo.Message)
	}
	de1 := g.Group("/demo1")
	{
		var c *gin.Context
		//权限认证中间件
		de1.Use(oauth2.AuthValidate(c))
		de1.GET("/message",demo.Message1)
	}
	g.Run(":"+viper.GetString("server.port"))
}

5.修改goOauth.go文件

实现四种保存token方法,切换保存方法只需要修改配置文件 tokenStore: file # mongo redis memory file 数据库的信息也从配置文件读取

package oauth2

import (
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"github.com/google/uuid"
	"github.com/spf13/viper"
	"gopkg.in/go-oauth2/mongo.v3"
	oredis "gopkg.in/go-oauth2/redis.v3"
	"gopkg.in/oauth2.v3"
	"gopkg.in/oauth2.v3/errors"
	"gopkg.in/oauth2.v3/manage"
	"gopkg.in/oauth2.v3/models"
	"gopkg.in/oauth2.v3/server"
	"gopkg.in/oauth2.v3/store"
	"log"
	"logistics/model"
	"os"
	"time"
)

var (
	gServer      *server.Server
	gClient      *store.ClientStore
	gManage      *manage.Manager
	baseResponse  *model.Base
	credentialsResponse *model.Credentials
)

/**
统一token返回格式
 */
func SetExtensionFields(ti oauth2.TokenInfo) map[string]interface{}{
	data := map[string]interface{}{
		"code": 1,
		"message":  "success",
	}
	return data
}

func init()  {
	work, _ := os.Getwd()
	viper.SetConfigName("oauth")
	viper.SetConfigType("yml")
	viper.AddConfigPath(work + "/conf")
	viper.ReadInConfig()
    storeType := viper.GetString("oauth.tokenStore")
	accessTokenExp := time.Duration(viper.GetInt("oauth.accessTokenExp"))
	refreshTokenExp := time.Duration(viper.GetInt("oauth.refreshTokenExp"))
	var isGenerateRefresh bool
	if viper.GetInt("oauth.isGenerateRefresh") == 1{
		isGenerateRefresh = true
	}else{
		isGenerateRefresh = false
	}
	gManage = manage.NewDefaultManager()
	switch storeType {
		case "mongo":
			viper.SetConfigName("mongo")
			viper.SetConfigType("yml")
			viper.AddConfigPath(work + "/conf")
			viper.ReadInConfig()
			mHost := viper.GetString("mongo.host")
			mPort := viper.GetString("mongo.port")
			mUser := viper.GetString("mongo.user")
			mPass := viper.GetString("mongo.pass")
			mDb := viper.GetString("mongo.dbName")
			gManage.MapTokenStorage(
				mongo.NewTokenStore(mongo.NewConfig(
					"mongodb://"+mUser+":"+mPass+"@"+mHost+":"+mPort+"/"+mDb,
					mDb,
				)),
			)
		case "memory":
			gManage.MustTokenStorage(store.NewMemoryTokenStore())
		case "redis":
			viper.SetConfigName("redis")
			viper.SetConfigType("yml")
			viper.AddConfigPath(work + "/conf")
			viper.ReadInConfig()
			rHost := viper.GetString("redis.host")
			rPort := viper.GetString("redis.port")
			rDb := viper.GetInt("redis.db")
			rPass := viper.GetString("redis.pass")
			gManage.MapTokenStorage(oredis.NewRedisStore(&redis.Options{
				Addr: rHost+":"+rPort,
				DB: rDb,
				Password: rPass,
			}))
		case "file":
			gManage.MustTokenStorage(store.NewFileTokenStore("token.db"))
	}

	gClient = store.NewClientStore()
	gManage.MapClientStorage(gClient)
	gServer = server.NewDefaultServer(gManage)
	gServer.SetAllowGetAccessRequest(true)
	gServer.SetClientInfoHandler(server.ClientFormHandler)
	var cfg = &manage.Config{
		AccessTokenExp: time.Hour * accessTokenExp,
		RefreshTokenExp: time.Hour * 24 * refreshTokenExp,
		IsGenerateRefresh: isGenerateRefresh,
	}
	gManage.SetAuthorizeCodeTokenCfg(cfg)
	gManage.SetRefreshTokenCfg(manage.DefaultRefreshTokenCfg)
    gManage.SetClientTokenCfg(cfg)
	gServer.SetExtensionFieldsHandler(SetExtensionFields)
	gServer.SetInternalErrorHandler(func(err error) (re *errors.Response) {
		log.Println("Internal Error:", err.Error())
		return
	})

	gServer.SetResponseErrorHandler(func(re *errors.Response) {
		log.Println("Response Error:", re.Error.Error())
	})
}


func TokenRequest(c *gin.Context){
	gServer.HandleTokenRequest(c.Writer, c.Request)
}

func Credentials(c *gin.Context){
	clientId := uuid.New().String()[:16]
	clientSecret := uuid.New().String()[:16]
	err := gClient.Set(clientId, &models.Client{
		ID:     clientId,
		Secret: clientSecret,
		Domain: "http://localhost:9094",
	})
	if err != nil {
		baseResponse = &model.Base{}
		baseResponse.Code = 1000
		baseResponse.Message = err.Error()
		c.JSON(500, baseResponse)
		c.Abort()
	}
	credentialsResponse = &model.Credentials{}
	credentialsResponse.Code = 1
	credentialsResponse.Message = "success"
	credentialsResponse.ClientId = clientId
	credentialsResponse.ClientSecret = clientSecret
	c.JSON(200, credentialsResponse)
}

/**
权限验证中间件
 */
func AuthValidate(c *gin.Context) gin.HandlerFunc{
	return func(c *gin.Context) {
		_, err := gServer.ValidationBearerToken(c.Request)
		if err != nil {
			baseResponse = &model.Base{}
			baseResponse.Code = 1001
			baseResponse.Message = err.Error()
			c.JSON(401, baseResponse)
			c.Abort()
			return
		}else{
			c.Next()
		}

	}
}


6.源码

源码

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部