Skip to content

Commit

Permalink
提出公共方法 & discord
Browse files Browse the repository at this point in the history
  • Loading branch information
shadow88sky committed Apr 23, 2023
1 parent 786b991 commit 9e7267a
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 23 deletions.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ require (
gorm.io/gorm v1.25.0
)

require github.com/gorilla/websocket v1.4.2 // indirect

require (
github.com/bwmarrin/discordgo v0.27.1
github.com/bytedance/sonic v1.8.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY=
github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.8.0 h1:ea0Xadu+sHlu7x5O3gKhRpQ1IKiMrSiHttPF0ybECuA=
github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
Expand Down Expand Up @@ -31,6 +33,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
Expand Down Expand Up @@ -96,6 +100,7 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
Expand Down
57 changes: 40 additions & 17 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"os"

"github.com/KNN3-Network/oauth-server/utils"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"github.com/joho/godotenv"
"go.uber.org/zap"
Expand Down Expand Up @@ -43,6 +42,10 @@ func main() {
r.GET("/oauth/github", func(c *gin.Context) {
code := c.Query("code")
jwtToken := c.Query("jwt")
if code == "" {
c.AbortWithError(http.StatusBadRequest, fmt.Errorf("No authorization code provided."))
return
}
logger.Info("github oauth认证", zap.String("code", code))
// 使用OAuth配置对象中定义的Exchange方法,通过code获取access token
token, err := githubOauthConfig.Exchange(c, code)
Expand All @@ -59,25 +62,14 @@ func main() {
c.Redirect(http.StatusTemporaryRedirect, "/error")
return
}
// 解析JWT
parsedToken, err := jwt.Parse(jwtToken, func(token *jwt.Token) (interface{}, error) {
// 验证算法和密钥
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("invalid signing method")
}
return []byte("my_secret_key"), nil
})

db := utils.GetDB()
address, err := utils.JwtDecode(jwtToken)
if err != nil {
logger.Error("解析token失败:", zap.Error(err))
}

claims, ok := parsedToken.Claims.(jwt.MapClaims)
if !ok || !parsedToken.Valid {
logger.Error("token不符合规范")
logger.Error("failed to get user info:", zap.Error(err))
c.Redirect(http.StatusTemporaryRedirect, "/error")
return
}
db := utils.GetDB()
address := claims["address"].(string)
github := userInfo["login"].(string)
email, ok := userInfo["email"].(string)
if !ok {
Expand All @@ -94,6 +86,37 @@ func main() {

c.Redirect(http.StatusTemporaryRedirect, "https://topscore.social")
})

// github oauth
r.GET("/oauth/discord", func(c *gin.Context) {
code := c.Query("code")
if code == "" {
logger.Error("No authorization code provided.")
// todo 需要给个error页面
c.Redirect(http.StatusTemporaryRedirect, "/error")
}
token, err := utils.ExchangeCodeForToken(code)
if err != nil {
logger.Error("Unable to exchange authorization code for access token", zap.Error(err))
c.Redirect(http.StatusTemporaryRedirect, "/error")
return
}
user, err := utils.FetchUser(token)
if err != nil {
logger.Error("Unable to fetch user information:", zap.Error(err))
return
}
fmt.Println(user)
// address, err := utils.JwtDecode(jwtToken)
if err != nil {
logger.Error("failed to get user info:", zap.Error(err))
c.Redirect(http.StatusTemporaryRedirect, "/error")
return
}
// fmt.Println(address)
c.Redirect(http.StatusTemporaryRedirect, "https://topscore.social")
})

r.Run(":8001")
}

Expand Down
82 changes: 82 additions & 0 deletions utils/discord.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package utils

import (
"encoding/json"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"

discord "github.com/bwmarrin/discordgo"
"github.com/joho/godotenv"
"golang.org/x/oauth2"
)

var clientID, clientSecret, redirectURI string

func init() {
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
clientID = os.Getenv("DISCORD_ID")
clientSecret = os.Getenv("DISCORD_SECRET")
redirectURI = "http://localhost:8001/oauth/discord"
}

func ExchangeCodeForToken(code string) (*oauth2.Token, error) {
form := url.Values{}
form.Add("client_id", clientID)
form.Add("client_secret", clientSecret)
form.Add("grant_type", "authorization_code")
form.Add("code", code)
form.Add("redirect_uri", redirectURI)

resp, err := http.PostForm("https://discordapp.com/api/oauth2/token", form)
if err != nil {
return nil, err
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

var token oauth2.Token
err = json.Unmarshal(body, &token)
if err != nil {
return nil, err
}

return &token, nil
}

func FetchUser(token *oauth2.Token) (*discord.User, error) {
req, err := http.NewRequest("GET", "https://discordapp.com/api/users/@me", nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+token.AccessToken)

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

var user discord.User
err = json.Unmarshal(body, &user)
if err != nil {
return nil, err
}

return &user, nil
}
29 changes: 29 additions & 0 deletions utils/jwt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package utils

import (
"fmt"

"github.com/dgrijalva/jwt-go"
)

func JwtDecode(jwtToken string) (string, error) {
// 解析JWT
parsedToken, err := jwt.Parse(jwtToken, func(token *jwt.Token) (interface{}, error) {
// 验证算法和密钥
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("invalid signing method")
}
return []byte("my_secret_key"), nil
})

if err != nil {
return "", err
}

claims, ok := parsedToken.Claims.(jwt.MapClaims)
if !ok || !parsedToken.Valid {
return "", err
}
address := claims["address"].(string)
return address, nil
}
8 changes: 2 additions & 6 deletions utils/zap.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,11 @@ func init() {

consoleDebugging := zapcore.Lock(os.Stdout)
consoleEncoder := zapcore.NewConsoleEncoder(encoderCfg)
consoleLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < zapcore.WarnLevel
})
consoleLevel := zapcore.DebugLevel
consoleCore := zapcore.NewCore(consoleEncoder, consoleDebugging, consoleLevel)

fileEncoder := zapcore.NewJSONEncoder(encoderCfg)
fileLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
return lvl < zapcore.WarnLevel
})
fileLevel := zapcore.DebugLevel
fileCore := zapcore.NewCore(fileEncoder, ws, fileLevel)

// 创建一个新的 Core,将两个子 Core 组合起来
Expand Down

0 comments on commit 9e7267a

Please sign in to comment.