up
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -55,7 +54,7 @@ func main() {
|
|||||||
}))
|
}))
|
||||||
router.GET("/", func(ctx *gin.Context) { ctx.Writer.WriteString("hello world") })
|
router.GET("/", func(ctx *gin.Context) { ctx.Writer.WriteString("hello world") })
|
||||||
router.GET("/auth/github", githubLoginHandler)
|
router.GET("/auth/github", githubLoginHandler)
|
||||||
router.GET("/auth/signin/sso", githubCallbackHandler)
|
// router.POST("/auth/signin/sso", )
|
||||||
|
|
||||||
router.Run(":8000")
|
router.Run(":8000")
|
||||||
}
|
}
|
||||||
@@ -75,61 +74,6 @@ func githubLoginHandler(c *gin.Context) {
|
|||||||
c.Redirect(http.StatusFound, url)
|
c.Redirect(http.StatusFound, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func githubCallbackHandler(c *gin.Context) {
|
|
||||||
code, state := c.Query("code"), c.Query("state")
|
|
||||||
session := sessions.Default(c)
|
|
||||||
savedState := session.Get("state")
|
|
||||||
if savedState == nil || savedState.(string) != state {
|
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid state parameter."})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用 code 换取 token
|
|
||||||
token, err := oauthConf.Exchange(context.Background(), code)
|
|
||||||
if err != nil {
|
|
||||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("授权失败: %s", err.Error())})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Println("token:", &token.AccessToken)
|
|
||||||
|
|
||||||
// 使用 token 获取 GitHub 用户信息
|
|
||||||
client := github.NewClient(oauthConf.Client(context.Background(), token))
|
|
||||||
// client := github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(token)))
|
|
||||||
user, _, err := client.Users.Get(c.Request.Context(), "")
|
|
||||||
if err != nil {
|
|
||||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": fmt.Errorf("获取用户信息失败: %s", err.Error())})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// err = storeUserToDB(user)
|
|
||||||
// if err != nil {
|
|
||||||
// log.Println("Error storing user to DB:", err)
|
|
||||||
// c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"message": "Internal server error"})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
log.Printf("%#v\n", user)
|
|
||||||
log.Println(user.GetEmail(), user.GetName(), user.GetID(), user.GetAvatarURL())
|
|
||||||
// 处理用户信息
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"id": user.ID,
|
|
||||||
"login": user.Login,
|
|
||||||
"name": user.Name,
|
|
||||||
"email": user.Email,
|
|
||||||
"location": user.Location,
|
|
||||||
"scopes": token.Extra("scope"),
|
|
||||||
})
|
|
||||||
// jwtToken, err := generateJWTToken(*user.ID)
|
|
||||||
// if err != nil {
|
|
||||||
// log.Println("Error generating JWT token:", err)
|
|
||||||
// c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"message": "Internal server error"})
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// c.SetCookie("token", jwtToken, 60*60*24, "/", "localhost", false, true)
|
|
||||||
// c.Redirect(http.StatusFound, "http://152.70.110.4:8000")
|
|
||||||
}
|
|
||||||
|
|
||||||
func initDB() {
|
func initDB() {
|
||||||
dsn := os.Getenv("MYSQL_DSN")
|
dsn := os.Getenv("MYSQL_DSN")
|
||||||
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||||
|
|||||||
97
services/board/auth.go
Normal file
97
services/board/auth.go
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package board
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/google/go-github/github"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
oauthConf = &oauth2.Config{
|
||||||
|
ClientID: os.Getenv("GITHUB_CLIENT_ID"),
|
||||||
|
ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
|
||||||
|
// Scopes: []string{"read:user", "user:email"},
|
||||||
|
Endpoint: oauth2.Endpoint{
|
||||||
|
AuthURL: "https://github.com/login/oauth/authorize",
|
||||||
|
TokenURL: "https://github.com/login/oauth/access_token",
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
|
||||||
|
type SignIn struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SSOSignIn struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
State string `json:"state"`
|
||||||
|
RedirectURI string `json:"redirectUri"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SignUp struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func SSOHandler(c *gin.Context) {
|
||||||
|
signin := SSOSignIn{}
|
||||||
|
|
||||||
|
session := sessions.Default(c)
|
||||||
|
savedState := session.Get("state")
|
||||||
|
if savedState == nil || savedState.(string) != signin.State {
|
||||||
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid state parameter."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 code 换取 token
|
||||||
|
token, err := oauthConf.Exchange(context.Background(), signin.Code)
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": fmt.Errorf("授权失败: %s", err.Error())})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("token:", &token.AccessToken)
|
||||||
|
|
||||||
|
// 使用 token 获取 GitHub 用户信息
|
||||||
|
client := github.NewClient(oauthConf.Client(context.Background(), token))
|
||||||
|
// client := github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(token)))
|
||||||
|
user, _, err := client.Users.Get(c.Request.Context(), "")
|
||||||
|
if err != nil {
|
||||||
|
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": fmt.Errorf("获取用户信息失败: %s", err.Error())})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// err = storeUserToDB(user)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Println("Error storing user to DB:", err)
|
||||||
|
// c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"message": "Internal server error"})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
log.Printf("%#v\n", user)
|
||||||
|
log.Println(user.GetEmail(), user.GetName(), user.GetID(), user.GetAvatarURL())
|
||||||
|
// 处理用户信息
|
||||||
|
c.JSON(http.StatusOK, gin.H{
|
||||||
|
"id": user.ID,
|
||||||
|
"login": user.Login,
|
||||||
|
"name": user.Name,
|
||||||
|
"email": user.Email,
|
||||||
|
"location": user.Location,
|
||||||
|
"scopes": token.Extra("scope"),
|
||||||
|
})
|
||||||
|
// jwtToken, err := generateJWTToken(*user.ID)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Println("Error generating JWT token:", err)
|
||||||
|
// c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"message": "Internal server error"})
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
// c.SetCookie("token", jwtToken, 60*60*24, "/", "localhost", false, true)
|
||||||
|
// c.Redirect(http.StatusFound, "http://152.70.110.4:8000")
|
||||||
|
}
|
||||||
@@ -9,3 +9,10 @@ type user struct {
|
|||||||
AvatarUrl string `json:"avatar_Url,omitempty"` // 用户在GitHub上的头像URL(如果有)。
|
AvatarUrl string `json:"avatar_Url,omitempty"` // 用户在GitHub上的头像URL(如果有)。
|
||||||
CreatedAt string `json:"created_At,omitempty"` // 记录插入到数据库中的时间。
|
CreatedAt string `json:"created_At,omitempty"` // 记录插入到数据库中的时间。
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Auth struct {
|
||||||
|
Type string
|
||||||
|
Code string
|
||||||
|
State string
|
||||||
|
RedirectUrl string
|
||||||
|
}
|
||||||
|
|||||||
12
services/board/user.go
Normal file
12
services/board/user.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package board
|
||||||
|
|
||||||
|
type UserCreate struct {
|
||||||
|
// Domain specific fields
|
||||||
|
Username string `json:"username"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Nickname string `json:"nickname"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
PasswordHash string
|
||||||
|
OpenID string
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user