ลองทำ 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
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
CILENT_ID=xxx
CILENT_SECRET=xxx

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

a

  • step การขอ AccessToken + UserInfo

a


facebook-oauth

September 12, 2020