Skip to content

Commit

Permalink
Add: facebook oauth2
Browse files Browse the repository at this point in the history
  • Loading branch information
MrXu committed Apr 20, 2016
1 parent 1aa4e41 commit 512b078
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 2 deletions.
135 changes: 135 additions & 0 deletions auth/socialFacebook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package auth

import (
"encoding/json"
"errors"
"io/ioutil"
"net/http"

"github.com/gin-gonic/gin"
"golang.org/x/oauth2"
)

const SocialFacebook string = "socialFacebook"

const FacebookProfileUrl string = "https://graph.facebook.com/v2.2/me?fields=id,name,email,picture,first_name,last_name"

var passportOauth *oauth2.Config

type FacebookProfile struct {
Id string `json:"id"`
Email string `json:"email"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Hd string `json:"hd"`
Locale string `json:"locale"`
Name string `json:"name"`
Picture struct {
Data struct {
Url string `json:"url"`
} `json:"data"`
} `json:"picture"`
}

func ConfigFacebook(r *gin.RouterGroup, clientId string, secretKey string, redirectUrl string) {
facebookConfig := &oauth2.Config{
// ClientId: FBAppID(string), ClientSecret : FBSecret(string)
// Example - ClientId: "1234567890", ClientSecret: "red2drdff6e2321e51aedcc94e19c76ee"

ClientID: clientId, // change this to yours
ClientSecret: secretKey,
RedirectURL: redirectUrl, // 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",
},
}

passportOauth = facebookConfig

r.GET("/login", func(c *gin.Context) {
Login(facebookConfig, c)
})
r.GET("/callback", MiddlewareFacebook(), func(c *gin.Context) {
user, err := GetFacebookProfile(c)
if user == nil || err != nil {
c.AbortWithStatus(500)
return
}

c.JSON(http.StatusOK, *user)
})

}

func Routes(oauth *oauth2.Config, r *gin.RouterGroup) {
passportOauth = oauth

r.GET("/login", func(c *gin.Context) {
Login(oauth, c)
})
}

func Login(oauth *oauth2.Config, c *gin.Context) {
url := oauth.AuthCodeURL("")
c.Redirect(http.StatusFound, url)
}

func MiddlewareFacebook() gin.HandlerFunc {
return func(c *gin.Context) {
getProfile(c)
}
}

func GetFacebookProfile(c *gin.Context) (*FacebookProfile, error) {
user, exists := c.Get(SocialFacebook)
if !exists {
return nil, errors.New("GinPassportFacebook namespace key doesn't exist")
}

return user.(*FacebookProfile), nil
}

func getProfile(c *gin.Context) {
c.Request.ParseForm()

config := passportOauth
code := c.Request.Form.Get("code")

t, err := config.Exchange(oauth2.NoContext, code)

if t == nil {
c.Redirect(301, "/")
return
} else if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}

client := config.Client(oauth2.NoContext, t)

resp, err := client.Get(FacebookProfileUrl)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}

defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body)

if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}

var userInformation FacebookProfile
err = json.Unmarshal(contents, &userInformation)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}

c.Set(SocialFacebook, &userInformation)
c.Next()
}
6 changes: 5 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
{"Address":"[email protected]", "Password":"testing","Host":"mail.google.com","Port":465},
{"Address":"[email protected]", "Password":"testing","Host":"mail.google.com","Port":465}
],
"Jwtkey":"testing"
"Jwtkey":"testing",
"Facebook":{
"ClientID":"yourid",
"ClientSecret":"yoursecret"
}
}
16 changes: 16 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type Configuration struct{
MongoDBUrl string
Emails []Email
Jwtkey string

Facebook FacebookClient
}

type Email struct{
Expand All @@ -24,6 +26,11 @@ type Email struct{
Port int
}

type FacebookClient struct{
ClientID string
ClientSecret string
}



func GetConfig(){
Expand All @@ -43,6 +50,7 @@ func GetConfig(){
// remove the two line below
fmt.Println("JWTKey: ",Config.Jwtkey)
fmt.Println("Emails: ",Config.Emails)
fmt.Println("Facebook:",Config.Facebook.ClientID)
}

func GetJwtKey() string{
Expand All @@ -59,4 +67,12 @@ func GetAnEmail() (Email,error) {

func GetMongoDBUrl() string{
return Config.MongoDBUrl
}

func GetFacebookClientId() string{
return Config.Facebook.ClientID
}

func GetFacebookClientSecret() string {
return Config.Facebook.ClientSecret
}
3 changes: 2 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ func main() {
r.POST("/login", auth.LoginUserWithEmail)
r.POST("/signup/email", auth.SignUpWithEmail)
r.POST("/signup/email/verify-email", auth.ActivateAccountAfterEmailSignup)

facebookR := r.Group("facebook")
auth.ConfigFacebook(facebookR, Config.GetFacebookClientId(), Config.GetFacebookClientSecret(), "http://localhost:8080/facebook/callback")

/*
api requiring authentication
Expand Down

0 comments on commit 512b078

Please sign in to comment.