Skip to content

Instantly share code, notes, and snippets.

@porjo
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save porjo/8834533 to your computer and use it in GitHub Desktop.
Save porjo/8834533 to your computer and use it in GitHub Desktop.
Go oauth client for Reddit
package main
import (
"fmt"
"github.com/codegangsta/martini"
"github.com/porjo/goauth2/oauth"
"io/ioutil"
"log"
"net/http"
)
var config = &oauth.Config{
ClientId: "xxxxxxxx",
ClientSecret: "yyyyyyyyy",
Scope: "identity",
AuthURL: "https://ssl.reddit.com/api/v1/authorize?duration=permanent",
TokenURL: "https://ssl.reddit.com/api/v1/access_token",
RedirectURL: "http://myhost/reddit_oauth_callback",
TokenCache: oauth.CacheFile("oauth_cache.json"),
}
func main() {
m := martini.Classic()
m.Get("/reddit_oauth", redditHandler)
m.Get("/reddit_oauth_callback", callbackHandler) //Reddit redirects to this URL after authorize request
m.Run()
}
// URL to request once the oauth dance is complete
var requestURL = "https://oauth.reddit.com/api/v1/me"
func redditHandler(w http.ResponseWriter, r *http.Request) {
t := &oauth.Transport{Config: config}
// Does token exist?
// Try to pull the token from the cache; if this fails, we need to get one.
token, err := config.TokenCache.Token()
if err != nil || token.AccessToken == "" {
// No token. We need to get a new token
// Get an authorization code from the data provider.
// ("Please ask the user if I can access this resource.")
url := config.AuthCodeURL("state_string")
fmt.Printf("Redirecting to %s\n", url)
http.Redirect(w, r, url, http.StatusFound)
} else {
// Yes. Re-use token
t.Token = token
}
fmt.Printf("Token %s\n", token)
log.Printf("Requesting URL %s\n", requestURL)
// Make the request.
cres, err := t.Client().Get(requestURL)
if err != nil {
log.Fatal("Get:", err)
}
defer cres.Body.Close()
// Write the response to client
body, err := ioutil.ReadAll(cres.Body)
w.Write([]byte(body))
log.Printf("Got response %s\n", body)
}
func callbackHandler(w http.ResponseWriter, r *http.Request) {
t := &oauth.Transport{Config: config}
//Get the code from the response
code := r.FormValue("code")
println(code)
if code == "" {
w.WriteHeader(401)
w.Write([]byte("Auth Error in Reddit callback"))
return
}
// Exchange the received code for a token
token, err := t.Exchange(code)
if err != nil {
w.WriteHeader(401)
w.Write([]byte(err.Error()))
return
}
fmt.Printf("Token %s\n", token)
// Make the actual request using the cached token to authenticate.
// ("Here's the token, let me in!")
t.Token = token
w.Write([]byte("Congratulations, you've authenticated to Reddit!"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment