Initial commit
This commit is contained in:
114
login.go
Normal file
114
login.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package mgoapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
mgo "gopkg.in/mgo.v2"
|
||||
)
|
||||
|
||||
// LoginModel is interface for modules which can be used for the login route
|
||||
type LoginModel interface {
|
||||
LoginCheck(db *mgo.Database) (tokenData interface{}, err error)
|
||||
LoginResponse(token string) (interface{}, error)
|
||||
}
|
||||
|
||||
func (api *API) loginPostHandler(m LoginModel) func(c *gin.Context) {
|
||||
return func(c *gin.Context) {
|
||||
lM := newModelOf(m).(LoginModel)
|
||||
if err := c.Bind(lM); err != nil {
|
||||
c.JSON(500, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
session := api.DBSession.Copy()
|
||||
defer session.Close()
|
||||
db := session.DB(api.DBName)
|
||||
|
||||
tokenData, err := lM.LoginCheck(db)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if tokenData == nil {
|
||||
c.JSON(403, gin.H{
|
||||
"error": "login failed",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// build jwt
|
||||
jwtToken := jwt.New(jwt.GetSigningMethod("HS256"))
|
||||
oType := reflect.TypeOf(tokenData)
|
||||
var objectType string
|
||||
if oType.Kind() == reflect.Ptr {
|
||||
objectType = oType.Elem().Name()
|
||||
} else {
|
||||
objectType = oType.Name()
|
||||
}
|
||||
if objectType == "" {
|
||||
objectType = oType.String()
|
||||
}
|
||||
jwtToken.Claims = jwt.MapClaims{
|
||||
"object": tokenData,
|
||||
"type": objectType,
|
||||
"exp": time.Now().Add(time.Minute * 60).Unix(),
|
||||
}
|
||||
token, err := jwtToken.SignedString(api.jwtSecret)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
response, err := lM.LoginResponse(token)
|
||||
if err != nil {
|
||||
c.JSON(500, gin.H{
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, response)
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateAuthToken checks if token is valid and returns its data
|
||||
func (c *Context) ValidateAuthToken() (tokenObject map[string]interface{}, tokenType string, err error) {
|
||||
token := c.Request.Header.Get(c.API.authenticationHeader)
|
||||
if token == "" {
|
||||
return nil, "", errors.New("empty token")
|
||||
}
|
||||
jwtToken, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
|
||||
return []byte(c.API.jwtSecret), nil
|
||||
})
|
||||
|
||||
if jwtToken == nil || jwtToken.Claims == nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if err := jwtToken.Claims.Valid(); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
claims := jwtToken.Claims.(jwt.MapClaims)
|
||||
|
||||
_object, ok := claims["object"].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, "", errors.New("token object data is invalid")
|
||||
}
|
||||
_type, ok := claims["type"].(string)
|
||||
if !ok {
|
||||
return nil, "", errors.New("token object type is invalid")
|
||||
}
|
||||
|
||||
return _object, _type, err
|
||||
}
|
||||
Reference in New Issue
Block a user