package router import ( "context" "crypto/rand" "encoding/base64" "io" "log" "net/http" "time" "github.com/coreos/go-oidc" "github.com/gin-gonic/gin" "golang.org/x/oauth2" ) var ( // clientID = os.Getenv("GOOGLE_OAUTH2_CLIENT_ID") // clientSecret = os.Getenv("GOOGLE_OAUTH2_CLIENT_SECRET") clientID = "godopu-dev" clientSecret = "mydwxdd-c2hbo6zcmab1mzj232zx4" ) var config oauth2.Config var provider *oidc.Provider func init() { var err error provider, err = oidc.NewProvider(context.Background(), "https://auth.godopu.com") if err != nil { log.Fatal(err) } config = oauth2.Config{ ClientID: clientID, ClientSecret: clientSecret, Endpoint: provider.Endpoint(), RedirectURL: "http://localhost:4000/auth/oidc.callback", Scopes: []string{oidc.ScopeOpenID, "profile", "email"}, } } func randString(nByte int) (string, error) { b := make([]byte, nByte) if _, err := io.ReadFull(rand.Reader, b); err != nil { return "", err } return base64.RawURLEncoding.EncodeToString(b), nil } func setCallbackCookie(ctx *gin.Context, name, value string) { // ctx.SetCookie(name, value, int(time.Hour.Seconds()), "", "", ctx.Request.TLS != nil, true) c := &http.Cookie{ Name: name, Value: value, MaxAge: int(time.Hour.Seconds()), Secure: ctx.Request.TLS != nil, HttpOnly: true, } http.SetCookie(ctx.Writer, c) } func authStart(ctx *gin.Context) { state, err := randString(16) if err != nil { http.Error(ctx.Writer, "Internal error", http.StatusInternalServerError) return } setCallbackCookie(ctx, "state", state) rurl := config.AuthCodeURL(state) ctx.Redirect(http.StatusPermanentRedirect, rurl) } func authCallback(ctx *gin.Context) { state, err := ctx.Cookie("state") if err != nil { http.Error(ctx.Writer, "state not found", http.StatusBadRequest) return } if ctx.Query("state") != state { http.Error(ctx.Writer, "state did not match", http.StatusBadRequest) return } oauth2Token, err := config.Exchange(ctx, ctx.Query("code")) if err != nil { http.Error(ctx.Writer, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError) return } userInfo, err := provider.UserInfo(ctx, oauth2.StaticTokenSource(oauth2Token)) if err != nil { http.Error(ctx.Writer, "Failed to get userinfo: "+err.Error(), http.StatusInternalServerError) return } _ = userInfo c := &http.Cookie{ Name: "__edit_access_token_", Value: "value", MaxAge: int(time.Hour.Seconds()), Secure: ctx.Request.TLS != nil, HttpOnly: true, Path: "/", } ctx.Set("__edit_access_token_", "^^") http.SetCookie(ctx.Writer, c) ctx.Redirect(http.StatusFound, "/edit") }