1
0

[Go言語]LINE ログイン連携方法 メモ

Posted at

概要

  • 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"
    }
    

参考情報

1
0
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
1
0