概要
- Go言語でLINEログイン連携する方法についてメモする。
LINEログイン シーケンス
- 以下のようなLINEログイン連携シーケンスをGo言語で実装する。
事前準備
ライブラリインストール
OAuth2.0 連携用ライブラリ
go get golang.org/x/oauth2
LINEログインチャネル作成
「ウェブアプリにLINEログインを組み込む」に従い、連携に必要な設定情報の登録、取得を行う。
コード
-
main.go
- localhost:8080でテスト用Webアプリケーションを起動し、上記シーケンス処理を行う。
-
LINE Channel Settings
に事前準備で取得した連携設定情報を入力する。
package main
import (
"crypto/rand"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"golang.org/x/net/context"
"golang.org/x/oauth2"
)
// LINE OAuth2.0 Endpoint
var endpoint = oauth2.Endpoint{
AuthURL: "https://access.line.me/oauth2/v2.1/authorize",
TokenURL: "https://api.line.me/oauth2/v2.1/token",
}
// LINE Channel Settings
var (
// Channel ID
clientID = "YOUR_CHANNEL_ID"
// Channel Secret
clientSecret = "YOUR_CHANNEL_SECRET"
// Redirection Endpoint
redirectURL = "YOUR_CHANNEL_REDIRECT_URL"
// CSRF Param
state = GenerateState()
)
// OAuth2.0 Settings
var oauth2Config = &oauth2.Config{
ClientID: clientID,
ClientSecret: clientSecret,
RedirectURL: redirectURL,
Scopes: []string{"profile", "openid"},
Endpoint: endpoint,
}
// UserInfo From LINE
type UserInfo struct {
UserID string `json:"userId"`
DisplayName string `json:"displayName"`
PictureURL string `json:"pictureUrl"`
}
// Generate CSRF Param
func GenerateState() string {
b := make([]byte, 32)
if _, err := rand.Read(b); err != nil {
return ""
}
// base64 Encoding
return base64.URLEncoding.EncodeToString(b)
}
func main() {
http.HandleFunc("/", handleMain)
http.HandleFunc("/login", handleLogin)
http.HandleFunc("/callback", handleCallback)
fmt.Println("Test Server Activated :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handleMain(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<html><body><a href=\"/login\">LINE Login by Go Lang</a></body></html>")
}
func handleLogin(w http.ResponseWriter, r *http.Request) {
url := oauth2Config.AuthCodeURL(state)
http.Redirect(w, r, url, http.StatusFound)
}
func handleCallback(w http.ResponseWriter, r *http.Request) {
if r.FormValue("state") != state {
http.Error(w, "State Check Failed", http.StatusBadRequest)
return
}
// Call OAuth2.0 Token Endpoint
token, err := oauth2Config.Exchange(oauth2.NoContext, r.FormValue("code"))
if err != nil {
http.Error(w, "Token Exchange Failed: "+err.Error(), http.StatusInternalServerError)
return
}
// Call User Profile Endpoint
client := oauth2Config.Client(context.Background(), token)
resp, err := client.Get("https://api.line.me/v2/profile")
if err != nil {
http.Error(w, "Failed to get user info: "+err.Error(), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
http.Error(w, "Failed to read user info: "+err.Error(), http.StatusInternalServerError)
return
}
var userInfo UserInfo
if err := json.Unmarshal(data, &userInfo); err != nil {
http.Error(w, "Failed to parse user info: "+err.Error(), http.StatusInternalServerError)
return
}
prettyJSON, err := json.MarshalIndent(userInfo, "", " ")
if err != nil {
http.Error(w, "Failed to generate pretty JSON: "+err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "User Info: %s", string(prettyJSON))
}
動作確認
- 以下のコマンドを実行し、テスト用Webアプリケーションを起動する。
go run .\main.go
Test Server Activated :8080
-
http://localhost:8080にアクセスする。
-
「LINE Login by Go Lang」をクリックし、LINEログインする。
-
以下のようなユーザー情報が表示されることを確認する。
User Info: { "userId": "xxx", "displayName": "XXX", "pictureUrl": "https://profile.line-scdn.net/xxx" }