Golang : Login(Authenticate) with Facebook example
By today's Internet standard, if you want to create a website or app that allows user to login, it won't be complete without a Facebook login button.
In this tutorial, we will explore how to :
- generate a Facebook Login URL string and bind a "Login with Facebook" button to the URL.
- generate access token from the returned
code
after login successfully. - dump out all the data returned by Facebook (depending on the scope - email, userbirthday, userlocation, useraboutme).
- get some data such as id, birthday, username and profile photo.
Please take note that, this tutorial uses couple of third party packages :
"github.com/golang/oauth2"
"github.com/antonholmquist/jason"
NOTE : Because I've executed this code in one of my Digital Ocean's droplet with an IP-address instead of domain name. I need to "fool" the Facebook Developers App Setting by setting the Mobile Site URL
to http://<ip address>:8080/
at https://developers.facebook.com/apps/<app id>/settings/
. You don't have to do this if you are executing the code in the domain name specified in the Facebook App Site URL
setting.
NOTE : This tutorial assumes that you've setup your Facebook App and already have the AppID and Secret.
Here you go :
package main
import (
"fmt"
"github.com/antonholmquist/jason"
"github.com/golang/oauth2"
"net/http"
"strconv"
"strings"
)
type AccessToken struct {
Token string
Expiry int64
}
func readHttpBody(response *http.Response) string {
fmt.Println("Reading body")
bodyBuffer := make([]byte, 5000)
var str string
count, err := response.Body.Read(bodyBuffer)
for ; count > 0; count, err = response.Body.Read(bodyBuffer) {
if err != nil {
}
str += string(bodyBuffer[:count])
}
return str
}
//Converts a code to an Auth_Token
func GetAccessToken(client_id string, code string, secret string, callbackUri string) AccessToken {
fmt.Println("GetAccessToken")
//https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&redirect_uri=YOUR_REDIRECT_URI&client_secret=YOUR_APP_SECRET&code=CODE_GENERATED_BY_FACEBOOK
response, err := http.Get("https://graph.facebook.com/oauth/access_token?client_id=" +
client_id + "&redirect_uri=" + callbackUri +
"&client_secret=" + secret + "&code=" + code)
if err == nil {
auth := readHttpBody(response)
var token AccessToken
tokenArr := strings.Split(auth, "&")
token.Token = strings.Split(tokenArr[0], "=")[1]
expireInt, err := strconv.Atoi(strings.Split(tokenArr[1], "=")[1])
if err == nil {
token.Expiry = int64(expireInt)
}
return token
}
var token AccessToken
return token
}
func Home(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
// generate loginURL
fbConfig := &oauth2.Config{
// ClientId: FBAppID(string), ClientSecret : FBSecret(string)
// Example - ClientId: "1234567890", ClientSecret: "red2drdff6e2321e51aedcc94e19c76ee"
ClientID: "", // change this to yours
ClientSecret: "",
RedirectURL: "http://<domain name and don't forget port number if you use one>/FBLogin", // change this to your webserver adddress
Scopes: []string{"email", "user_birthday", "user_location", "user_about_me"},
Endpoint: oauth2.Endpoint{
AuthURL: "https://www.facebook.com/dialog/oauth",
TokenURL: "https://graph.facebook.com/oauth/access_token",
},
}
url := fbConfig.AuthCodeURL("")
// Home page will display a button for login to Facebook
w.Write([]byte("<html><title>Golang Login Facebook Example</title> <body> <a href='" + url + "'><button>Login with Facebook!</button> </a> </body></html>"))
}
func FBLogin(w http.ResponseWriter, r *http.Request) {
// grab the code fragment
w.Header().Set("Content-Type", "text/html; charset=utf-8")
code := r.FormValue("code")
ClientId := "" // change this to yours
ClientSecret := ""
RedirectURL := "http://<domain name and don't forget port number if you use one>/FBLogin"
accessToken := GetAccessToken(ClientId, code, ClientSecret, RedirectURL)
response, err := http.Get("https://graph.facebook.com/me?access_token=" + accessToken.Token)
// handle err. You need to change this into something more robust
// such as redirect back to home page with error message
if err != nil {
w.Write([]byte(err.Error()))
}
str := readHttpBody(response)
// dump out all the data
// w.Write([]byte(str))
// see https://www.socketloop.com/tutorials/golang-process-json-data-with-jason-package
user, _ := jason.NewObjectFromBytes([]byte(str))
id, _ := user.GetString("id")
email, _ := user.GetString("email")
bday, _ := user.GetString("birthday")
fbusername, _ := user.GetString("username")
w.Write([]byte(fmt.Sprintf("Username %s ID is %s and birthday is %s and email is %s<br>", fbusername, id, bday, email)))
img := "https://graph.facebook.com/" + id + "/picture?width=180&height=180"
w.Write([]byte("Photo is located at " + img + "<br>"))
// see https://www.socketloop.com/tutorials/golang-download-file-example on how to save FB file to disk
w.Write([]byte("<img src='" + img + "'>"))
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", Home)
mux.HandleFunc("/FBLogin", FBLogin)
http.ListenAndServe(":8080", mux)
}
Output :
References :
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+26.3k Golang : Encrypt and decrypt data with AES crypto
+45.6k Golang : Read tab delimited file with encoding/csv package
+36k Golang : Validate IP address
+8.5k Golang : Random integer with rand.Seed() within a given range
+6.7k Golang : constant 20013 overflows byte error message
+6.6k Mac/Linux/Windows : Get CPU information from command line
+14.4k Golang : Get URI segments by number and assign as variable example
+7.9k Golang : HTTP Server Example
+20.5k Golang : Convert PNG transparent background image to JPG or JPEG image
+5.6k Unix/Linux : How to test user agents blocked successfully ?
+10.2k Android Studio : Simple input textbox and intercept key example
+13.2k Golang : Read XML elements data with xml.CharData example