ບົດຄວາມນີ້ເຮົາຈະມາລອງສ້າງລະບົບ OAuth Facebook, ສັງເກດເວລາທີ່ເຮົາຈະເຂົ້າໃຊ້ລະບົບລະໃດໜຶ່ງຈະເຫັນວ່າມີປຸ່ມໃຫ້ກົດ Login with Facebook, Login with Google...ຈະເຫັນວ່າມີປຸ່ມໃຫ້ກົດປະມານນີ້, ນັ້ນແຫຼະຄື OAuth ນັ້ນເອງ.
OAuth ຫຼື Open Authentication ເປັນມາດຕະຖານການຢືນຢັນຕົວຕົນ ແລະ ການກວດສອບສິດທິບຸກຄົນອີກຮູບແບບໜຶ່ງໂດຍຕ້ອງໃຫ້ຜູ້ໃຊ້ທຳການຍອມຮັບບາງຢ່າງໃຫ້ Application ເພື່ອເຂົ້າເຖິງຂໍ້ມູນບາງສ່ວນຂອງບຸກຄົນ.
ຂັ້ນຕອນ: ກ່ອນອື່ນໃຫ້ເຮົາໄປທີ່ => https://developers.facebook.com/ ທຳການສະໝັກສະມາຊິກໃຫ້ຮຽບຮ້ອຍຫຼັງຈາກນັ້ນກໍໄປສ້າງແອັບຕາມຂັ້ນຕອນດັ່ງນີ້
1/ ກົດທີ່ MyApps ແລ້ວກົດ CreateApp ດ້ານຂ້ວາມືໃຫ້ເລືອກປະເພດແອັບເປັນ None
2/ ຕັ້ງຊື່ແອັບ ແລະ ໃສ່ອີເມວໃຫ້ຮຽບຮ້ອຍກົດສ້າງໄດ້ເລີຍ
3/ ຫຼັງຈາກທີ່ເຮົາສ້າງແອັບສຳເລັດແລ້ວເຮົາຈະໄດ້ key: App ID, App secret ເຮົາຈະເອົາໄປໃສ່ຕອນທີ່ເຮົາສ້າງ API ເປັນ config parameter
4/ ໄປຕັ້ງຄ່າ Platform ໃນທີ່ນີ້ເຮົາຈະທົດລອງຢູ່ Web browser ໃຫ້ໄປທີ່ Settings->Basic ເລືອນລົງມາທາງລຸ່ມແລ້ວກົດ Add platform ເລືອກ Website ກົດ Next
5/ ກຳນົດ Site URL ໃນທີ່ນີ້ເຮົາຈະ dev ຢູ່ local ເຮົາເອງກຳນົດເປັນ http://localhost:8080
6/ ເມື່ອກຳນົດ Site URL ແລ້ວຖ້າຈະໃສ່ Callback URI ໃຫ້ໃສ່ຢູ່ທີ່ຊ່ອງ Valid OAuth Redirect URIs ຕົວຢ່າງ: http://localhost:8080/callback
OAuth Facebook Flow
ຊິອະທິບາຍການເຮັດວຽກຂອງມັນຄາວໆຄື:
1/ ເຮົາຕ້ອງສ້າງ Service ໂຕໜຶ່ງຂຶ້ນມາເມື່ອມີການກົດຍິງເຂົ້າມາ Service ຕົວນີ້ປຶບມັນຈະທຳການ redirect ໄປຫາ https://www.facebook.com/v17.0/dialog/oauth
2/ ເມື່ອເຮົາທຳການ Authorize App Facebook ສຳເລັດແລ້ວ Facebook ຈະທຳການ redirect ກັບມາຫາເຮົາຕາມ Url Callback ທີ່ເຮົາໄດ້ກຳນົດໄວ້, ຕາມດ້ວຍ Query Params code ສົ່ງ key token ກັບມາຫາເຮົາ
3/ ຫລັງຈາກນັ້ນເຮົາຈະເອົາ key token ທີ່ໄດ້ມາຈາກ Facebook ເຮົາກໍນຳເອົາ Implement ລຳດັບທັດໄປຖ້າຕ້ອງການໄປດຶ່ງເອົາຂໍ້ມູນພື້ນຖານຈາກ facebook ເຊັ່ນ: ລະຫັດ,ຊື່,ອີເມວ...ໂດຍທີ່ເຮົາສົ່ງ key token ເພື່ອໄປຂໍທີ່ https://graph.facebook.com/v17.0/oauth/access_token
ເອົາລ່ະມາຮອດຂັ້ນຕອນເຮົາ Codeding ກັນເລີຍ
1/ ສ້າງ Service Login ຕົວຢ່າງໃນ file main.go
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"github.com/labstack/echo/v4/middleware"
"github.com/labstack/echo/v4"
)
const (
ClientID = "YOUR_APPID"
ClientSecret = "YOUR_APP_SECRET"
RedirectURL = "YOUR_CALLBACK_URL"
)
const htmlIndex = `<html><body> Logged in with <a href="/login">facebook</a></body></html>`
func handleMain(c echo.Context) error {
return c.HTML(http.StatusOK, htmlIndex)
}
func handleLogin(c echo.Context) error {
authURL := "https://www.facebook.com/v17.0/dialog/oauth"
params := url.Values{}
params.Set("client_id", ClientID)
params.Set("redirect_uri", RedirectURL)
params.Set("response_type", "code")
params.Set("scope", "email")
redirectURL := authURL + "?" + params.Encode()
return c.Redirect(http.StatusTemporaryRedirect, redirectURL)
}
func main() {
e := echo.New()
e.Use(
middleware.RequestID(),
middleware.Logger(),
middleware.Recover(),
)
e.GET("/", handleMain)
e.GET("/login", handleLogin)
fmt.Println("Started running on http://localhost:8080")
log.Fatal(e.Start(":8080"))
}
ທົດສອບກົດທີ່ລິ້ງ Logged in with facebook
ຖ້າບໍ່ມີຫາຫຍັງກໍຈະໄດ້ຜົນຫຼັບດັ່ງຮູບລຸ່ມນີ້
ເມື່ອເຮົາກົດ Continue ສັ່ງເກດເບິ່ງ Url Facebook ຈະທຳການ Redirect ກັບມາ Url ຕາມທີ່ເຮົາກຳນົດ
2/ ສ້າງ Service Callback ເພື່ອຮອງຮັບເພີ່ມໃນ file main.go
e.GET("/callback", handleCallback)
3/ ເພີ່ມຟັງຊັນ handleCallback ຖ້າເຮັດຖືກຕ້ອງສຳເລັດທຳການ return accessToken ອອກໄປ
func handleCallback(c echo.Context) error {
code := c.QueryParam("code")
if code == "" {
return c.String(http.StatusBadRequest, "Authorization code not found.")
}
// Exchange the authorization code for an access token
tokenURL := "https://graph.facebook.com/v17.0/oauth/access_token"
params := url.Values{}
params.Set("client_id", ClientID)
params.Set("client_secret", ClientSecret)
params.Set("redirect_uri", RedirectURL)
params.Set("code", code)
resp, err := http.PostForm(tokenURL, params)
if err != nil {
log.Println("Failed to exchange code for token:", err)
return c.String(http.StatusInternalServerError, "Failed to exchange code for token.")
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Println("Failed to exchange code for token:", resp.Status)
return c.String(http.StatusInternalServerError, "Failed to exchange code for token.")
}
var tokenResp struct {
AccessToken string `json:"access_token"`
}
dec := json.NewDecoder(resp.Body)
if err := dec.Decode(&tokenResp); err != nil {
log.Println("Failed to parse token response:", err)
return c.String(http.StatusInternalServerError, "Failed to parse token response.")
}
return c.JSON(http.StatusOK, echo.Map{
"accessToken": tokenResp.AccessToken,
})
}
ກໍຈະໄດ້ accessToken ຕອບຈາກ Facebook ແບບນີ້
4/ ຫຼັງຈາກທີ່ໄດ້ accessToken ແລ້ວເຮົາກໍນຳເອົາໄປ Get user ເພື່ອເອົາຂໍ້ມູນພື້ນຖານເຊັ່ນ: ລະຫັດ,ຊື່,ອີເມວ ໃຫ້ອັບເດດຟັງຊັນ handleCallback ດັ່ງນີ້
func handleCallback(c echo.Context) error {
code := c.QueryParam("code")
if code == "" {
return c.String(http.StatusBadRequest, "Authorization code not found.")
}
// Exchange the authorization code for an access token
tokenURL := "https://graph.facebook.com/v17.0/oauth/access_token"
params := url.Values{}
params.Set("client_id", ClientID)
params.Set("client_secret", ClientSecret)
params.Set("redirect_uri", RedirectURL)
params.Set("code", code)
resp, err := http.PostForm(tokenURL, params)
if err != nil {
log.Println("Failed to exchange code for token:", err)
return c.String(http.StatusInternalServerError, "Failed to exchange code for token.")
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Println("Failed to exchange code for token:", resp.Status)
return c.String(http.StatusInternalServerError, "Failed to exchange code for token.")
}
var tokenResp struct {
AccessToken string `json:"access_token"`
}
dec := json.NewDecoder(resp.Body)
if err := dec.Decode(&tokenResp); err != nil {
log.Println("Failed to parse token response:", err)
return c.String(http.StatusInternalServerError, "Failed to parse token response.")
}
fmt.Println("tokenResp.AccessToken: ", tokenResp.AccessToken)
userFacebook, err := getUserFacebook(c.Request().Context(), tokenResp.AccessToken)
if err != nil {
return c.JSON(http.StatusInternalServerError, err)
}
return c.JSON(http.StatusOK, echo.Map{
"userFacebook": userFacebook,
})
}
ຸ5/ ເພີ່ມຟັງ getUserFacebook
type UserDetail struct {
ID string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func getUserFacebook(ctx context.Context, token string) (*UserDetail, error) {
url := "https://graph.facebook.com/me?fields=id,name,email&access_token=" + token
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to do request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
var user UserDetail
dec := json.NewDecoder(resp.Body)
if err := dec.Decode(&user); err != nil {
return nil, fmt.Errorf("failed to decode response: %w", err)
}
return &user, nil
}
ທົດສອບ Login ອີກຄັ້ງກໍຈະໄດ້ຜົນຫຼັບອອກມາແບບນີ້
ມາຮອດນີ້ຖືກວ່າສຳເລັດແລ້ວ 5555 ສຳລັບການທົດລອງສ້າງ OAuth Facebook ໃນ go Basic ເບື້ອງຕົ້ນກໍຈະມີປະມານນີ້, ມີອັນໃດຜິດພາດບໍ່ຄົບຖ້ວນກະຂໍອະໄພນຳເດີຜູ້ຂຽນເອງກໍຫາເລີ່ມໃຊ້ຄືກັນສາມາດແນະນຳເພີ່ມຕື່ມໄດ້
ຂອບໃຈທີ່ອ່ານຈົບ
Top comments (0)