4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Go言語でLineLoginしてmidとアクセストークンを取得する(ライブラリ書いた)

Posted at

(エピソード0)
もともとはLineBotでTwitter情報を流してみようと思いたったところからはじまる。
LineアカウントとTwitterアカウントの連携が必要だな。
TwitterのGo OAuthクライアントはふむふむAnacondaで使ってるやつでいいか。
Lineは、、あれ、見つからないな。
あー、LineのOAuth仕様って楽ちんだからみんなイチから書いてるのか。
うーんでも少しでも楽したい人はいるだろうしサンプルにもなるよね。
みんGo読んで意識高くなったしGithubに公開だ。
カキカキ。
コード量すくねぇーー
けどせっかくだし誰かの役に立つことを祈って公開しよう。キータも書こう。。

githubはここ

やりたいこと

  • LineでOAuthログインしたい
  • REST API用のアクセストークンを取得したい

LineでOAuthログイン

Lineの画像を拾ってくるなりして適当なログインボタンを作る。
ログインボタンをポチったときのリクエスト先でこんな感じにハンドリングする。

func (f GetLineOauthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        l := linein.NewLinein(clientId, clientSecret)
        url, values, err := l.GetWebLoginURL("http://"+r.Host+"/line_auth_callback", "") 
        if err != nil {
                fmt.Fprintf(w, "%v", err)
                return
        }   
        http.Redirect(w, r, url+"?"+values.Encode(), http.StatusFound)
}

あ、lineinパッケージはimportしてある前提です。
import "github.com/matsuoky/linein"

clientId clientSecret はLineLoginのチャネルを作成した際に表示される Channel ID, Channel Secret をセットする。
ID, Secretを未取得の方は こちら のリンクからどうぞ

話もどって、、するとLineさんが用意してくれているログイン画面にリダイレクトされる。
遷移後のログイン画面でログインすると l.GetWebLoginURL("http://"+r.Host+"/line_auth_callback", "") でセットしたコールバックURLにさらにリダイレクトされる。

コールバック先でのハンドリングはこんな感じ。

func (f GetLineAuthCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
        code := r.FormValue("code")
        if code == "" {
                fmt.Fprintf(w, "code is not found")
                return
        }
        l := linein.NewLinein(clientId, clientSecret)
        url, values, err := l.GetAccessTokenURL(code, "")
        if err != nil {
                fmt.Fprintf(w, "GetAccessTokenURL: %v", err)
                return
        }
        c := appengine.NewContext(r)
        client := urlfetch.Client(c)
        res, err := linein.Post(client, url, values)
        if err != nil {
                fmt.Fprintf(w, "line auth post err: %v", err)
                return
        }
        defer res.Body.Close()
        lUser := new(LineUser)
        if err := json.NewDecoder(res.Body).Decode(lUser); err != nil {
                fmt.Fprintf(w, "decode err: %v", err)
                return
        }
        ...

ここに来た時点ではまだREST API用のアクセストークンもユーザ情報も入っていない。
これらを取得するために必要な一時的なトークン(code)が入っている。
ではアクセストークンを取得するためのURLとパラメータを取得。

url, values, err := l.GetAccessTokenURL(code, "")

valuesはnet/url.Values型なのでこれをそのままPostすればOK。
一応Postのラッパーも用意しているので今回はこれを使う。

res, err := linein.Post(nil, url, values)

appengineユーザはここでHTTPクライアントを入れ替える。

c := appengine.NewContext(r)
client := urlfetch.Client(c)
res, err := linein.Post(client, url, values)

レスポンスをデコードする際に使う型の例。

type LineUser struct {
        Mid          string `json:"mid"`
        AccessToken  string `json:"access_token"`
        ExpiresIn    int    `json:"expires_in"`
        RefreshToken string `json:"refresh_token"`
}

AccessToken の値を利用すればLineの提供するREST APIを使える。
Mid の値を保存してログイン用の識別子として使いログイン機能を実装できる。
また、Messaging API で使用されるUserIdとMidは一致するはず。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?