golang gin框架实现oauth2

golang gin框架实现oauth2

golang gin框架实现oauth2

1.获取依赖包

go get github.com/gin-gonic/gingo get gopkg.in/oauth2.v3go get github.com/google/uuid

2.项目结构和源码

​​项目地址​​

3.主要文件说明

main.go

package mainimport ( "github.com/gin-gonic/gin" "logistics/demo" "logistics/oauth2")func main() { 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(":9096")}

ginOauth.go

package oauth2import ( "github.com/gin-gonic/gin" "github.com/google/uuid" "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" "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() { gManage = manage.NewDefaultManager() gManage.MustTokenStorage(store.NewMemoryTokenStore()) gClient = store.NewClientStore() gManage.MapClientStorage(gClient) gServer = server.NewDefaultServer(gManage) gServer.SetAllowGetAccessRequest(true) gServer.SetClientInfoHandler(server.ClientFormHandler) var cfg = &manage.Config{AccessTokenExp: time.Hour * 200, RefreshTokenExp: time.Hour * 24 * 300, IsGenerateRefresh: true} 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: " }) 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() } }}

base.go

package modeltype Base struct { Code int `json:"code"` Message string `json:"message"`}

credentials.go

package modeltype Credentials struct { Base ClientId string `json:"clientId"` ClientSecret string `json:"clientSecret"`}

test.go

package demoimport "github.com/gin-gonic/gin"func Message(c *gin.Context){ c.JSON(200, "I not need auth")}func Message1(c *gin.Context){ c.JSON(200, "I need auth")}

4.说明

代码中的

clientId := uuid.New().String()[:16] clientSecret := uuid.New().String()[:16]

可以修改成固定值方便测试

5.请求

首先获取Credentials ​​返回结果

{ "code": 1, "message": "success", "clientId": "a02156b4-1a46-43", "clientSecret": "98871767-3760-46"}

然后再获取accessToken ​​返回结果

{ "access_token": "DK0LDFEHPEA19DCBXN8-2W", "code": 1, "expires_in": 720000, "message": "success", "refresh_token": "YCLVAWSKWGIV___ZNJIGDQ", "scope": "all", "token_type": "Bearer"}

原来是没有code和message,为了统一增加的。

请求接口 ​​这个不需要授权可以访问 返回结果

"I not need auth"

请求接口 ​​不加授权返回

{ "code": 1001, "message": "invalid access token"}

增加授权返回

"I need auth"