|  | @@ -5,7 +5,6 @@ import (
 | 
	
		
			
			| 5 | 5 |  	"github.com/dgrijalva/jwt-go"
 | 
	
		
			
			| 6 | 6 |  	"github.com/gin-gonic/gin"
 | 
	
		
			
			| 7 | 7 |  	"net/http"
 | 
	
		
			
			| 8 |  | -	"time"
 | 
	
		
			
			| 9 | 8 |  )
 | 
	
		
			
			| 10 | 9 |  
 | 
	
		
			
			| 11 | 10 |  const (
 | 
	
	
		
			
			|  | @@ -15,29 +14,27 @@ const (
 | 
	
		
			
			| 15 | 14 |  	ctxRequestTokenExpired        = "expired"
 | 
	
		
			
			| 16 | 15 |  )
 | 
	
		
			
			| 17 | 16 |  
 | 
	
		
			
			| 18 |  | -func Auth(authKey string) gin.HandlerFunc {
 | 
	
		
			
			|  | 17 | +func Auth(authKey string, session Session) gin.HandlerFunc {
 | 
	
		
			
			| 19 | 18 |  	return func(ctx *gin.Context) {
 | 
	
		
			
			| 20 |  | -		var (
 | 
	
		
			
			| 21 |  | -			err error
 | 
	
		
			
			| 22 |  | -			tk  = ctx.Request.Header.Get(ctxRequestHeaderAuthorization)
 | 
	
		
			
			| 23 |  | -		)
 | 
	
		
			
			|  | 19 | +		var tokenFromCookie, tokenFromHeader string
 | 
	
		
			
			| 24 | 20 |  
 | 
	
		
			
			| 25 |  | -		if tk == "" {
 | 
	
		
			
			| 26 |  | -			tk, err = ctx.Cookie(ctxRequestCookieAuthorization)
 | 
	
		
			
			| 27 |  | -			if err != nil {
 | 
	
		
			
			| 28 |  | -				ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "auth failed"})
 | 
	
		
			
			| 29 |  | -				return
 | 
	
		
			
			|  | 21 | +		tokenFromCookie, err := ctx.Cookie(ctxRequestCookieAuthorization)
 | 
	
		
			
			|  | 22 | +		if err != nil {
 | 
	
		
			
			|  | 23 | +			if err == http.ErrNoCookie {
 | 
	
		
			
			|  | 24 | +				tokenFromHeader = ctx.Request.Header.Get(ctxRequestHeaderAuthorization)
 | 
	
		
			
			| 30 | 25 |  			}
 | 
	
		
			
			|  | 26 | +		}
 | 
	
		
			
			| 31 | 27 |  
 | 
	
		
			
			| 32 |  | -			tk = "Bearer " + tk
 | 
	
		
			
			|  | 28 | +		if tokenFromHeader == "" {
 | 
	
		
			
			|  | 29 | +			tokenFromHeader = "Bearer " + tokenFromCookie
 | 
	
		
			
			| 33 | 30 |  		}
 | 
	
		
			
			| 34 | 31 |  
 | 
	
		
			
			| 35 |  | -		if len(tk) < 8 {
 | 
	
		
			
			|  | 32 | +		if len(tokenFromHeader) < 8 {
 | 
	
		
			
			| 36 | 33 |  			ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "auth failed"})
 | 
	
		
			
			| 37 | 34 |  			return
 | 
	
		
			
			| 38 | 35 |  		}
 | 
	
		
			
			| 39 | 36 |  
 | 
	
		
			
			| 40 |  | -		token, err := jwt.Parse(tk[7:], func(token *jwt.Token) (interface{}, error) {
 | 
	
		
			
			|  | 37 | +		token, err := jwt.Parse(tokenFromHeader[7:], func(token *jwt.Token) (interface{}, error) {
 | 
	
		
			
			| 41 | 38 |  			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
 | 
	
		
			
			| 42 | 39 |  				return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
 | 
	
		
			
			| 43 | 40 |  			}
 | 
	
	
		
			
			|  | @@ -50,25 +47,21 @@ func Auth(authKey string) gin.HandlerFunc {
 | 
	
		
			
			| 50 | 47 |  			return
 | 
	
		
			
			| 51 | 48 |  		}
 | 
	
		
			
			| 52 | 49 |  
 | 
	
		
			
			|  | 50 | +		if !session.IsExistsJwtToken(token.Signature) {
 | 
	
		
			
			|  | 51 | +			ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "auth failed, token expired by server"})
 | 
	
		
			
			|  | 52 | +			return
 | 
	
		
			
			|  | 53 | +		}
 | 
	
		
			
			|  | 54 | +
 | 
	
		
			
			| 53 | 55 |  		if mapClaims, ok := token.Claims.(jwt.MapClaims); ok {
 | 
	
		
			
			| 54 | 56 |  			if expired, ok := mapClaims[ctxRequestTokenExpired].(float64); ok {
 | 
	
		
			
			| 55 |  | -				switch true {
 | 
	
		
			
			| 56 |  | -				case expired > 0:
 | 
	
		
			
			| 57 |  | -					if int64(expired) < time.Now().Unix() {
 | 
	
		
			
			| 58 |  | -						ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "auth failed, token timeout"})
 | 
	
		
			
			| 59 |  | -						return
 | 
	
		
			
			| 60 |  | -					}
 | 
	
		
			
			|  | 57 | +				if expired == 0 && tokenFromCookie == "" {
 | 
	
		
			
			|  | 58 | +					if session.DeleteJwtToken(token.Raw) {
 | 
	
		
			
			|  | 59 | +						ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "auth failed, token expired"})
 | 
	
		
			
			| 61 | 60 |  
 | 
	
		
			
			| 62 |  | -					// todo check expired from server
 | 
	
		
			
			| 63 |  | -				case expired == 0:
 | 
	
		
			
			| 64 |  | -					// Only cookie is exists, check token expired. app expired by itself call logout when app exit
 | 
	
		
			
			| 65 |  | -					if _, err := ctx.Cookie(ctxRequestCookieAuthorization); err != nil {
 | 
	
		
			
			| 66 |  | -						ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "auth failed, token timeout"})
 | 
	
		
			
			| 67 |  | -						return
 | 
	
		
			
			|  | 61 | +					} else {
 | 
	
		
			
			|  | 62 | +						ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "auth failed, delete server token failed"})
 | 
	
		
			
			| 68 | 63 |  					}
 | 
	
		
			
			| 69 | 64 |  
 | 
	
		
			
			| 70 |  | -				default:
 | 
	
		
			
			| 71 |  | -					ctx.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"msg": "auth failed, token timeout"})
 | 
	
		
			
			| 72 | 65 |  					return
 | 
	
		
			
			| 73 | 66 |  				}
 | 
	
		
			
			| 74 | 67 |  
 |