Skip to content

Instantly share code, notes, and snippets.

@pzentenoe
Last active April 8, 2019 16:26
Show Gist options
  • Save pzentenoe/318dc684b2c6010b004edc9992a68380 to your computer and use it in GitHub Desktop.
Save pzentenoe/318dc684b2c6010b004edc9992a68380 to your computer and use it in GitHub Desktop.
Autenticacion con facebook con go y metodos para obtener informacion de usuario logeado
package handlers
import (
"encoding/json"
"fmt"
"github.com/labstack/echo"
"gitlab.com/skolldevs-backend/indahouse-api/database"
"gitlab.com/skolldevs-backend/indahouse-api/models"
"golang.org/x/oauth2"
"golang.org/x/oauth2/facebook"
"math/rand"
"net/http"
"net/url"
"strings"
)
//Configuracion OAUTH2
var (
oauthConf = &oauth2.Config{
ClientID: "393715834537710",
ClientSecret: "6af800526b2745953aef9d31f12e1252",
RedirectURL: "https://indahouse.cl/api/indahouse/api/v1/login/facebook/callback",
Scopes: []string{"public_profile"},
Endpoint: facebook.Endpoint,
}
oauthStateString = ""
)
type facebookModel struct {
ID string `json:"id"`
FirstName string `json:"first_name"`
MiddleName string `json:"middle_name"`
LastName string `json:"last_name"`
Email string `json:"email"`
Gender string `json:"gender"`
Birthday string `json:"birthday"`
}
type imageData struct {
Data struct {
Height int `json:"height"`
Is_silhouette bool `json:"is_silhouette"`
Url string `json:"url"`
Width int `json:"width"`
} `json:"data"`
}
func init() {
oauthStateString = string(rand.Int())
}
func HandleFacebookLogin(c echo.Context) error {
fmt.Println("Entrando al login")
Url, err := url.Parse(oauthConf.Endpoint.AuthURL)
if err != nil {
fmt.Println(err.Error())
return c.JSON(http.StatusBadRequest, echo.Map{"message": "No se pudo validar cuenta facebook favor reintente"})
}
parameters := url.Values{}
parameters.Add("client_id", oauthConf.ClientID)
parameters.Add("scope", strings.Join(oauthConf.Scopes, " "))
parameters.Add("redirect_uri", oauthConf.RedirectURL)
parameters.Add("response_type", "code")
fmt.Println("state : " + oauthStateString)
parameters.Add("state", oauthStateString)
Url.RawQuery = parameters.Encode()
url := Url.String()
fmt.Println("Redireccionando...")
fmt.Println(url)
return c.Redirect(http.StatusTemporaryRedirect, url)
}
func HandleFacebookCallback(c echo.Context) error {
fmt.Println("Entrando en handler de facebook")
state := c.FormValue("state")
if state != oauthStateString {
fmt.Printf("invalid oauth state, expected '%s', got '%s'\n", oauthStateString, state)
return c.JSON(http.StatusBadRequest, echo.Map{"message": "No se pudo validar el estado de oauth2"})
}
code := c.FormValue("code")
token, err := oauthConf.Exchange(oauth2.NoContext, code)
if err != nil {
fmt.Printf("oauthConf.Exchange() failed with '%s'\n", err)
return c.JSON(http.StatusBadRequest, echo.Map{"message": "No se pudo obtener token :" + err.Error()})
}
userData, err := getDataFromModel(token.AccessToken)
if err != nil {
return c.JSON(http.StatusBadGateway, echo.Map{"message": "Error al obtener informacion usuario"})
}
image_data, error := getImageInfo(userData.ID)
if error != nil {
return c.JSON(http.StatusBadGateway, echo.Map{"message": "Error al obtener imagen usuario"})
}
imagen := image_data.Data.Url
//Crear usuario y crear token
usuario, err := database.FindUsuarioByEmail(userData.Email)
if usuario.ID != "" && usuario.Facebook && err == nil {
//El usuario ya esta registrado se genera token y se logea
usuario.Password = ":)"
return crearRespuestaUsuarioToken(c, usuario)
} else if usuario.ID != "" && !usuario.Facebook {
//Ya existe usuario registrado hacer login
fmt.Println("Existe usuario se autentica con de usuario facebook")
usuario.Facebook = true
return autenticarUsuarioExistente(c, usuario, FACEBOOK)
} else {
fmt.Println("Creacion de usuario facebook")
//Crear usuario Facebook
apellidos := strings.Split(userData.LastName, " ")
materno := ""
if len(apellidos) > 1 {
materno = apellidos[1]
}
usuario := models.Usuario{}
usuario.Email = userData.Email
usuario.Nombres = userData.FirstName + " " + userData.MiddleName
usuario.ApellidoPaterno = apellidos[0]
usuario.ApellidosMaterno = materno
usuario.Imagen = imagen
usuario.Facebook = true
usuario.Estado = true
usuario.Password = ":)"
usuarioCreated, err := database.CreateUsuario(usuario)
if err != nil {
return c.JSON(http.StatusBadGateway, echo.Map{"message": "Error al crear usuario con facebook"})
}
return crearRespuestaUsuarioToken(c, usuarioCreated)
}
}
func getDataFromModel(access_token string) (*facebookModel, error) {
resp, err := http.Get("https://graph.facebook.com/me?fields=id,first_name,middle_name,last_name,gender,birthday,email&access_token=" + url.QueryEscape(access_token))
if err != nil {
return nil, err
}
data := new(facebookModel)
defer resp.Body.Close()
erro := json.NewDecoder(resp.Body).Decode(data)
if erro != nil {
return nil, erro
}
return data, nil
}
func getImageInfo(userId string) (*imageData, error) {
resp, err := http.Get("https://graph.facebook.com/" + userId + "/picture?type=large&redirect=false")
if err != nil {
return nil, err
}
data := new(imageData)
defer resp.Body.Close()
erro := json.NewDecoder(resp.Body).Decode(data)
if erro != nil {
return nil, erro
}
return data, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment