-
Notifications
You must be signed in to change notification settings - Fork 2
/
require_auth.go
76 lines (68 loc) · 2.11 KB
/
require_auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package basicserver
import (
"errors"
"strconv"
"strings"
jwt "github.com/dgrijalva/jwt-go"
"github.com/globalsign/mgo/bson"
"github.com/kataras/iris"
)
// RequireAuth is a middleware used by routes which require authentication.
//
// It checks request `Authorization` header and tries to parse it.
//
// If everything goes well with parsing, then the "uid" value is passed to Next().
//
// In case of invalid/expired token, this returns status code `401` and `text/plain`
// error message as a response.
//
// In case of single login enabled and locked token provided, this returns status code `409`.
//
func (app *BasicApp) RequireAuth() iris.Handler {
return func(ctx iris.Context) {
authHeader := ctx.GetHeader("Authorization")
if len(authHeader) == 0 {
app.HandleError(errors.New("No Authorization Header"), ctx, iris.StatusUnauthorized)
return
}
tokenString := strings.Replace(authHeader, "Bearer ", "", 1)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return app.Settings.Secret, nil
})
if err != nil {
app.HandleError(err, ctx, iris.StatusUnauthorized)
return
}
uid := token.Claims.(jwt.MapClaims)["uid"]
if uid == nil {
err := errors.New("Incorrect Authorization Header")
app.HandleError(err, ctx, iris.StatusUnauthorized)
return
}
objectUID := bson.ObjectIdHex(uid.(string))
var user User
err = app.Coll.Users.FindId(objectUID).One(&user)
if err != nil {
if err.Error() == "not found" {
err := errors.New("No Such User")
app.HandleError(err, ctx, iris.StatusUnauthorized)
ctx.WriteString("No Such User")
} else {
app.HandleError(err, ctx, iris.StatusInternalServerError)
}
return
} else if app.Settings.SingleLogin && // handle single login
strconv.FormatInt(user.LastLoginAt.Unix(), 10) != token.Claims.(jwt.MapClaims)["sl"] {
err := errors.New("Token Locked")
app.HandleError(err, ctx, iris.StatusConflict)
return
}
// pass on the "uid"
ctx.Values().Set("uid", uid)
if app.Settings.SingleLogin {
sl := token.Claims.(jwt.MapClaims)["sl"]
ctx.Values().Set("sl", sl)
}
ctx.Next()
}
}