ลองทำ Facebook Login ด้วย Facebook Oauth


Oauth คือไร

อ่านได้จากที่นี้

เรียนรู้ OAuth


ทำ Facebook

Manually Build a Login Flow - Facebook Login - Documentation - Facebook for Developers

Step 1 สร้าง App

a

a

Step 2 Get AppId and AppSecret

a


Step 3 ทดสอบ ยิงไปหา service facebook

  • ก่อนอื่นทำหน้า รับ code ที่จะส่งกลับมา (ในที่นี้ทำ ง่ายๆ ด้วยการทำ api method Get ตัวนึง)

a

  • จากนั้น เปิดไปที่ url sh https://www.facebook.com/v8.0/dialog/oauth \ ?client_id=<cilent id> \ &redirect_uri=<callback uri> \ &scope=email \ &state=""

parameter - client_id - redirect_uri - scope - state

a a

Step 4 ยิงไปหา service Facebook เพื่อขอ Access Token

https://graph.facebook.com/v8.0/oauth/access_token \
?client_id=<cilent id> \
&redirect_uri=<callback url> \
&client_secret=<client secret> 
&code=<code from callback>

parameter - client_id - redirect_uri - client_secret - code

a

Step 5 เอา Access Token ไป Get UserInfo

// header : authorization : Bearer <Token From Step 4>
https://graph.facebook.com/v8.0/me?fields=id,name,email

parameter - fields -> id,name,email

a

หากจะดึงรูปด้วย


ทดสอบทำ Api จาก Flow ด้่านบน

"github.com/labstack/echo/v4"
  • Service.go
package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

var client_id = os.Getenv("CILENT_ID")
var client_secret = os.Getenv("CILENT_SECRET")
var redirect_uri = "http://localhost:1323/"

func getTokenBearer(code string) (Token, ErrorResponse) {
	uri := fmt.Sprintf(`https://graph.facebook.com/v8.0/oauth/access_token?client_id=%s&redirect_uri=%s&client_secret=%s&code=%s`, client_id, redirect_uri, client_secret, code)
	resp, err := http.Get(uri)
	if err != nil {
		print(err)
	}
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	var data map[string]interface{}
	json.Unmarshal(body, &data)
	if err := data["error"]; err != nil {
		err := data["error"].(map[string]interface{})
		return Token{}, ErrorResponse{
			Error:        http.StatusText(http.StatusBadRequest),
			ErrorCode:    http.StatusBadRequest,
			ErrorMessage: err["message"],
		}
	}
	return Token{AccessToken: data["access_token"].(string)}, ErrorResponse{}
}
func getUserInfo(token string) Response {
	uri := "https://graph.facebook.com/v8.0/me?fields=id,name,email"
	req, err := http.NewRequest("GET", uri, nil)
	req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	response, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer response.Body.Close()
	body2, _ := ioutil.ReadAll(response.Body)
	/// return
	var result Response
	json.Unmarshal(body2, &result.Datas)
	result.Datas.Image = fmt.Sprintf("https://graph.facebook.com/%s/picture?type=large", result.Datas.ID)
	return result
}

  • Response.go
package main

type Response struct {
	Datas ResponseData `json:"datas"`
}

type ResponseData struct {
	Email string `json:"email"`
	Name  string `json:"name"`
	ID    string `json:"id"`
	Image string `json:"image"`
}
type Token struct {
	AccessToken string `json:"access_token"`
}

type ErrorResponse struct {
	Error        string      `json:"error"`
	ErrorCode    interface{} `json:"error_code"`
	ErrorMessage interface{} `json:"error_messages"`
}
  • main.go
package main

import (
	"fmt"
	"net/http"
	"os"

	_ "github.com/joho/godotenv/autoload"
	"github.com/labstack/echo/v4"
)

func main() {
	e := echo.New()
	e.GET("/", func(c echo.Context) error {
		return c.JSON(http.StatusOK, map[string]string{"message": "hello"})
	})
	e.GET("/oauth/facebook", func(c echo.Context) error {
		client_id := os.Getenv("CILENT_ID")
		uri := fmt.Sprintf("https://www.facebook.com/v8.0/dialog/oauth?client_id=%&redirect_uri=http://localhost:1323/&scope=email&state=null", client_id)
		return c.Redirect(http.StatusPermanentRedirect, uri)
	})
	e.GET("/oauth/facebook/userInfo", func(c echo.Context) error {
		// get Bearer Token
		token, err := getTokenBearer(c.QueryParam("code"))
		if err.ErrorCode == 400 {
			return c.JSON(400, err)
		}
		result := getUserInfo(token.AccessToken)
		return c.JSON(200, result)
	})
	e.Logger.Fatal(e.Start(":1323"))
}
  • .env sh CILENT_ID=xxx CILENT_SECRET=xxx

$ go mod init
$ go run .
  • step การขอ code เปิดไปที่ localhost:1323/oauth/facebook

a

  • step การขอ AccessToken + UserInfo

a


facebook-oauth