loginsrv

Unnamed repository; edit this file 'description' to name the repository.
git clone git@jamesshield.xyz:repos/loginsrv.git
Log | Files | Refs | README | LICENSE

facebook.go (2182B)


      1 package oauth2
      2 
      3 import (
      4 	"encoding/json"
      5 	"fmt"
      6 	"io/ioutil"
      7 	"net/http"
      8 	"strings"
      9 
     10 	"github.com/tarent/loginsrv/model"
     11 )
     12 
     13 var facebookAPI = "https://graph.facebook.com/v2.12"
     14 
     15 func init() {
     16 	RegisterProvider(providerfacebook)
     17 }
     18 
     19 // facebookUser is used for parsing the facebook response
     20 type facebookUser struct {
     21 	UserID  string `json:"id,omitempty"`
     22 	Picture struct {
     23 		Data struct {
     24 			URL string `json:"url,omitempty"`
     25 		} `json:"data,omitempty"`
     26 	} `json:"picture,omitempty"`
     27 	Name  string `json:"name,omitempty"`
     28 	Email string `json:"email,omitempty"`
     29 }
     30 
     31 var providerfacebook = Provider{
     32 	Name:          "facebook",
     33 	AuthURL:       "https://www.facebook.com/v2.12/dialog/oauth",
     34 	TokenURL:      "https://graph.facebook.com/v2.12/oauth/access_token",
     35 	DefaultScopes: "email",
     36 	GetUserInfo: func(token TokenInfo) (model.UserInfo, string, error) {
     37 		fu := facebookUser{}
     38 
     39 		url := fmt.Sprintf("%v/me?access_token=%v&fields=name,email,id,picture", facebookAPI, token.AccessToken)
     40 
     41 		// For facebook return an application/json Content-type the Accept header should be set as 'application/json'
     42 		client := &http.Client{}
     43 		contentType := "application/json"
     44 		req, _ := http.NewRequest("GET", url, nil)
     45 		req.Header.Set("Accept", contentType)
     46 		resp, err := client.Do(req)
     47 
     48 		if err != nil {
     49 			return model.UserInfo{}, "", err
     50 		}
     51 		defer resp.Body.Close()
     52 
     53 		if !strings.Contains(resp.Header.Get("Content-Type"), contentType) {
     54 			return model.UserInfo{}, "", fmt.Errorf("wrong content-type on facebook get user info: %v", resp.Header.Get("Content-Type"))
     55 		}
     56 
     57 		if resp.StatusCode != 200 {
     58 			return model.UserInfo{}, "", fmt.Errorf("got http status %v on facebook get user info", resp.StatusCode)
     59 		}
     60 
     61 		b, err := ioutil.ReadAll(resp.Body)
     62 		if err != nil {
     63 			return model.UserInfo{}, "", fmt.Errorf("error reading facebook get user info: %v", err)
     64 		}
     65 
     66 		err = json.Unmarshal(b, &fu)
     67 		if err != nil {
     68 			return model.UserInfo{}, "", fmt.Errorf("error parsing facebook get user info: %v", err)
     69 		}
     70 
     71 		return model.UserInfo{
     72 			Sub:     fu.UserID,
     73 			Picture: fu.Picture.Data.URL,
     74 			Name:    fu.Name,
     75 			Email:   fu.Email,
     76 			Origin:  "facebook",
     77 		}, string(b), nil
     78 	},
     79 }