init: 1.0.0
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/perfect-panel/ppanel-server/pkg/logger"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/google"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
RedirectURL string
|
||||
}
|
||||
type Client struct {
|
||||
*oauth2.Config
|
||||
}
|
||||
type UserInfo struct {
|
||||
OpenID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
Picture string `json:"picture"`
|
||||
VerifiedEmail bool `json:"verified_email"`
|
||||
}
|
||||
|
||||
func New(config *Config) *Client {
|
||||
return &Client{
|
||||
&oauth2.Config{
|
||||
ClientID: config.ClientID,
|
||||
ClientSecret: config.ClientSecret,
|
||||
RedirectURL: config.RedirectURL,
|
||||
Scopes: []string{"openid", "profile", "email", "https://www.googleapis.com/auth/user.phonenumbers.read"},
|
||||
Endpoint: google.Endpoint,
|
||||
},
|
||||
}
|
||||
}
|
||||
func (c *Client) GetUserInfo(token string) (*UserInfo, error) {
|
||||
client := c.Config.Client(context.Background(), &oauth2.Token{AccessToken: token})
|
||||
resp, err := client.Get("https://www.googleapis.com/oauth2/v2/userinfo")
|
||||
if err != nil {
|
||||
logger.Error("[Google OAuth 2.0] Get User Info", logger.Field("error", err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var userInfo map[string]interface{}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&userInfo); err != nil {
|
||||
logger.Error("[Google OAuth 2.0] Decode User Info", logger.Field("error", err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &UserInfo{
|
||||
OpenID: userInfo["id"].(string),
|
||||
Email: userInfo["email"].(string),
|
||||
Name: userInfo["name"].(string),
|
||||
Picture: userInfo["picture"].(string),
|
||||
VerifiedEmail: userInfo["verified_email"].(bool),
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package google
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
func TestGoogleOAuth(t *testing.T) {
|
||||
t.Skipf("Skip TestGoogleOAuth test")
|
||||
http.HandleFunc("/", handleMain)
|
||||
http.HandleFunc("/login", handleLogin)
|
||||
http.HandleFunc("/auth", handleCallback)
|
||||
http.HandleFunc("/user", handleAuth)
|
||||
|
||||
fmt.Println("Server is running on http://localhost:3001")
|
||||
log.Fatal(http.ListenAndServe(":3001", nil))
|
||||
}
|
||||
|
||||
func handleMain(w http.ResponseWriter, r *http.Request) {
|
||||
html := `<html>
|
||||
<body>
|
||||
<a href="/login">Log in with Google</a>
|
||||
</body>
|
||||
</html>`
|
||||
fmt.Fprint(w, html)
|
||||
}
|
||||
|
||||
func handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
oauthConfig := New(&Config{
|
||||
ClientID: "",
|
||||
ClientSecret: "",
|
||||
RedirectURL: "http://localhost:3001/auth",
|
||||
})
|
||||
url := oauthConfig.AuthCodeURL("randomstate", oauth2.AccessTypeOffline)
|
||||
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func handleCallback(w http.ResponseWriter, r *http.Request) {
|
||||
if r.FormValue("state") != "randomstate" {
|
||||
http.Error(w, "State is invalid", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("url: %v", r.URL)
|
||||
|
||||
oauthConfig := New(&Config{
|
||||
ClientID: "",
|
||||
ClientSecret: "Key",
|
||||
RedirectURL: "http://localhost:3001/auth",
|
||||
})
|
||||
code := r.FormValue("code")
|
||||
token, err := oauthConfig.Exchange(context.Background(), code)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to exchange token", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, "/user?token="+token.AccessToken, http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func handleAuth(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.FormValue("token")
|
||||
client := New(&Config{
|
||||
ClientID: "Id",
|
||||
ClientSecret: "Key",
|
||||
RedirectURL: "http://localhost:3001/auth",
|
||||
})
|
||||
userInfo, err := client.GetUserInfo(token)
|
||||
if err != nil {
|
||||
http.Error(w, "Failed to get user info", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, "Hello, %s", userInfo.Name)
|
||||
}
|
||||
Reference in New Issue
Block a user