golang gin框架oauth2 四种保存token方法
1.其它信息请参考项目
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()
}
}
}