Skip to content

Instantly share code, notes, and snippets.

@mattlockyer
Last active June 18, 2019 23:47
Show Gist options
  • Save mattlockyer/58d1063c7b973853fb56e87a7dd1e89f to your computer and use it in GitHub Desktop.
Save mattlockyer/58d1063c7b973853fb56e87a7dd1e89f to your computer and use it in GitHub Desktop.
Facebook Login for Web with Using Go Server.Validate token from web client POST request. FB API called with GET request. Reponse to client in JSON
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Facebook Login Example</title>
<meta name="description" content="Facebook Login Example">
<meta name="author" content="Matt Lockyer">
</head>
<body>
<div class="fb-login-button" data-width="" data-size="large" data-button-type="continue_with" data-auto-logout-link="false" data-use-continue-as="false"></div>
<div id="fb-root"></div>
<script crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.3&appId=xxxxxxxxxxxxxxx&autoLogAppEvents=1"></script>
<script>
window.onload = () => {
FB.getLoginStatus(async (response) => {
if (response.status === 'connected') {
const token = response.authResponse.accessToken
console.log(token)
const res = await fetch('http://localhost:8080/validate', {
method: 'POST', mode: "cors",
body: JSON.stringify({ token })
}).then((res) => json())
console.log(res)
}
})
}
</script>
</body>
</html>
package main
import (
"encoding/json"
"net/http"
)
/********************************
Accept TokenPayload from the client with only token field provided
Validate client token with fb api
Repond with TokenPayload fully or partially filled
********************************/
var access_token string = "xxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
type TokenPayload struct {
UserId string `json:"user_id"`
Token string `json:"token"`
Message string `json:"message"`
}
type msi = map[string]interface{}
func validate(w http.ResponseWriter, r *http.Request) {
// Read body
defer r.Body.Close()
// Unmarshal
var payload TokenPayload
err := json.NewDecoder(r.Body).Decode(&payload)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// Fetch response for payload.Token
r2, err := http.Get("https://graph.facebook.com/v3.3/debug_token?input_token=" +
payload.Token + "&access_token=" + access_token)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
defer r2.Body.Close()
var r3 msi
err = json.NewDecoder(r2.Body).Decode(&r3)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
// FB error will respond with object { "error": ... } and the below will panic
if r3["error"] != nil {
http.Error(w, err.Error(), 500)
return
}
fbData := r3["data"].(msi)
if (!fbData["is_valid"].(bool)) {
payload.Message = "FB token not valid"
} else {
payload.Message = "FB token is valid"
payload.UserId = fbData["user_id"].(string)
}
// Return output
output, err := json.Marshal(payload)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
w.Header().Set("content-type", "application/json")
w.Write(output)
}
func main() {
http.Handle("/", http.FileServer(http.Dir("./static")))
http.HandleFunc("/validate", validate)
http.ListenAndServe(":8080", nil)
println("Listening on 8080")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment