How do I get past oauth2 using golang and the yahoo fantasy sports API and gothic?

83 Views Asked by At

So I want to build a webapp that uses the yahoo fantasy sports api

The issue I am having is it requires me to use Oauth2 to be able to use it but I have never setup or used oauth2. I have been doing research on it and I tried to follow a few peoples tutorials for other apis and I can't get it to work. I am using Golang because I have the most familiarity with that language. I've gotten as far as getting the client and secret keys and then getting to the login page but I get an error when I go to the login page. I have been trying to use a package called Gothic to help and most of this code is directly based on the example code given on the Gothic packages page. If Gothic isn't a great way to do this though I am willing to use other packages.

Here is my code thusfar

package main

import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "os"
    "sort"

    "github.com/gorilla/pat"
    "github.com/markbates/goth"
    "github.com/markbates/goth/gothic"
    "github.com/markbates/goth/providers/openidConnect"
    "github.com/markbates/goth/providers/yahoo"
)

func main() {
    sessionSecret := os.Setenv("SESSION_SECRET","default_secret_value")
    if sessionSecret != nil {
        fmt.Println(sessionSecret)
    }
    

    goth.UseProviders(
        // Pointed localhost.com to http://localhost:3000/auth/yahoo/callback through proxy as yahoo
        // does not allow to put custom ports in redirection uri
        yahoo.New(os.Getenv("YAHOO_CLIENT_ID"), os.Getenv("YAHOO_SECRET_KEY"), "https://myurlname.com/auth/openid-connect/callback"),
    )
    // OpenID Connect is based on OpenID Connect Auto Discovery URL (https://openid.net/specs/openid-connect-discovery-1_0-17.html)
    // because the OpenID Connect provider initialize itself in the New(), it can return an error which should be handled or ignored
    // ignore the error for now
    openidConnect, _ := openidConnect.New(os.Getenv("OPENID_CONNECT_KEY"), os.Getenv("I don't actually have anything hooked up to this open id connect secret, I have tried using my client secret and it didn't work OPENID_CONNECT_SECRET"), "https://MYURLNAME/auth/openid-connect/callback", os.Getenv("I dont have this as an eviroment variable but i left it in anyways, normally this will probably be nil OPENID_CONNECT_DISCOVERY_URL"))
    if openidConnect != nil {
        goth.UseProviders(openidConnect)
    }

    m := map[string]string{
        "yahoo": "Yahoo",
    }
    var keys []string
    for k := range m {
        keys = append(keys, k)
    }
    sort.Strings(keys)

    providerIndex := &ProviderIndex{Providers: keys, ProvidersMap: m}

    p := pat.New()
    p.Get("/auth/{provider}/callback", func(res http.ResponseWriter, req *http.Request) {

        user, err := gothic.CompleteUserAuth(res, req)
        if err != nil {
            fmt.Fprintln(res, err)
            return
        }
        t, _ := template.New("foo").Parse(userTemplate)
        t.Execute(res, user)
    })

    p.Get("/logout/{provider}", func(res http.ResponseWriter, req *http.Request) {
        gothic.Logout(res, req)
        res.Header().Set("Location", "/")
        res.WriteHeader(http.StatusTemporaryRedirect)
    })

    p.Get("/auth/{provider}", func(res http.ResponseWriter, req *http.Request) {
        // try to get the user without re-authenticating
        if gothUser, err := gothic.CompleteUserAuth(res, req); err == nil {
            t, _ := template.New("foo").Parse(userTemplate)
            t.Execute(res, gothUser)
        } else {
            gothic.BeginAuthHandler(res, req)
        }
    })

    p.Get("/", func(res http.ResponseWriter, req *http.Request) {
        t, _ := template.New("foo").Parse(indexTemplate)
        t.Execute(res, providerIndex)
    })

    log.Println("listening on localhost:3000")
    log.Fatal(http.ListenAndServe(":3000", p))
}

type ProviderIndex struct {
    Providers    []string
    ProvidersMap map[string]string
}

var indexTemplate = `{{range $key,$value:=.Providers}}
        <p><a href="/auth/{{$value}}">Log in with {{index $.ProvidersMap $value}}</a></p>
    {{end}}`

var userTemplate = `
    <p><a href="/logout/{{.Provider}}">logout</a></p>
    <p>Name: {{.Name}} [{{.LastName}}, {{.FirstName}}]</p>
    <p>Email: {{.Email}}</p>
    <p>NickName: {{.NickName}}</p>
    <p>Location: {{.Location}}</p>
    <p>AvatarURL: {{.AvatarURL}} <img src="{{.AvatarURL}}"></p>
    <p>Description: {{.Description}}</p>
    <p>UserID: {{.UserID}}</p>
    <p>AccessToken: {{.AccessToken}}</p>
    <p>ExpiresAt: {{.ExpiresAt}}</p>
    <p>RefreshToken: {{.RefreshToken}}</p>
    `

I tried using the above code and I got &error=unauthorized_client&error_description=invalid+client+id in the url.

0

There are 0 best solutions below