GinでTwitter OAuthでaccess token取得
2017-09-10
バズるものを作れる瞬発力を身に付けたくてTwitterのOAuth認証使ってツイートできるやつを作れるようになっておきたかった。アイデアはまだ無い。 GoのWebアプリケーションフレームワーク Ginを使ってTwitter OAuthでトークン取得するところまで試してみた。
Ginの採用理由
さくっと書きたいからsinatra likeなやつを探した。 その中で現時点でGitHub Starが一番多そうなGinを選んだ。
- https://github.com/go-martini/martini
- https://github.com/zenazn/goji
- https://github.com/gin-gonic/gin
- https://github.com/gocraft/web
環境
前回のgo-twitterを使ってみた記事に引き続きCloud9( http://c9.io )さんを使いました。そろそろ有料プランも検討せねば。
http://92thunder.hatenablog.com/entry/2017/09/04/031706
go getできない
前回は大丈夫だったがgo getでエラーが発生したのでこちらを参考に解決した。 http://qiita.com/syossan27/items/ad05e5060d2ac0fd7adc
コード
main.go Ginって標準でsession使えないのか…って思いつつ追加した。
https://github.com/gin-gonic/contrib/tree/master/sessions
package main
import (
"flag"
"log"
"net/http"
"os"
"github.com/coreos/pkg/flagutil"
gt "github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
"github.com/dghubble/oauth1/twitter"
"github.com/gin-gonic/contrib/sessions"
"github.com/gin-gonic/gin"
)
func main() {
// 環境変数からconsumer-key, consumer-secretを取得
flags := flag.NewFlagSet("app-auth", flag.ExitOnError)
consumerKey := flags.String("consumer-key", "", "Twitter Consumer Key")
consumerSecret := flags.String("consumer-secret", "", "Twitter Consumer Secret")
flags.Parse(os.Args[1:])
flagutil.SetFlagsFromEnv(flags, "TWITTER")
if *consumerKey == "" || *consumerSecret == "" {
log.Fatal("Consumer key/secret required")
}
config := oauth1.Config{
ConsumerKey: *consumerKey,
ConsumerSecret: *consumerSecret,
Endpoint: twitter.AuthorizeEndpoint,
}
// ginのrouter初期化
router := gin.Default()
store := sessions.NewCookieStore([]byte("secret"))
// セッションの設定
router.Use(sessions.Sessions("oauth-tweet-test-session", store))
// templatesディレクトリを登録
router.LoadHTMLGlob("templates/*")
// GET /
// アクセストークンがセッションに入っていれば表示
// 入ってなければrequestTokenを取得してOAuth認証ページにリダイレクト
router.GET("/", func(c *gin.Context) {
session := sessions.Default(c)
accessToken := session.Get("access_token")
accessSecret := session.Get("access_secret")
if accessToken == nil || accessSecret == nil {
requestToken, requestSecret, _ := config.RequestToken()
session.Set("request_secret", requestSecret)
session.Save()
c.Redirect(http.StatusFound, "https://api.twitter.com/oauth/authenticate?oauth_token="+requestToken)
} else {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"test": "hello world",
})
}
})
// GET /callback
// OAuth認証ページからこのアプリを許可したらリダイレクトされてくる
// このあたりはTwitter Application Managementで設定
// URLに入っているoauth_token, oauth_verifierと
// GET /で取得していたrequestSecretを使ってアクセストークン取得
router.GET("/callback", func(c *gin.Context) {
oauthToken := c.Query("oauth_token")
oauthVerifier := c.Query("oauth_verifier")
session := sessions.Default(c)
requestSecret := session.Get("request_secret").(string)
accessToken, accessSecret, _ := config.AccessToken(oauthToken, requestSecret, oauthVerifier)
session.Set("access_token", accessToken)
session.Set("access_secret", accessSecret)
session.Save()
c.Redirect(http.StatusFound, "/")
})
// POST /post
// access token/secret を使ってツイート投稿する
router.POST("/post", func(c *gin.Context) {
session := sessions.Default(c)
accessToken := session.Get("access_token")
accessSecret := session.Get("access_secret")
if accessToken == nil || accessSecret == nil {
log.Fatal("Invalid access token/secret.")
}
config := oauth1.NewConfig(*consumerKey, *consumerSecret)
token := oauth1.NewToken(accessToken.(string), accessSecret.(string))
httpClient := config.Client(oauth1.NoContext, token)
client := gt.NewClient(httpClient)
client.Statuses.Update("oauth test", nil)
c.Redirect(http.StatusFound, "/")
})
router.Run()
}
templates/index.tmpl
<html>
<head>
</head>
<body>
<h3>OAuth Tweet Test</h3>
<form method="post" action="/post">
<button type="submit">Post</button>
</form>
</body>
</html>
実行
export TWITTER_CONSUMER_KEY=xxx
export TWITTER_CONSUMER_SECRET=xxx
go get .
go run main.go
認証ページにリダイレクトされてツイートするとこまでできた。
所感
- さくっとOAuthでトークン取得試せた
- Mac Bookのスペースキーに何か挟まってるのか打ちにくい