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.