@@ -3,6 +3,7 @@ package v1
3
3
import (
4
4
"errors"
5
5
"net/http"
6
+ "strconv"
6
7
"strings"
7
8
"time"
8
9
@@ -13,6 +14,12 @@ import (
13
14
"github.com/rs/zerolog/log"
14
15
)
15
16
17
+ const (
18
+ cookieNameToken = "hb.auth.token"
19
+ cookieNameRemember = "hb.auth.remember"
20
+ cookieNameSession = "hb.auth.session"
21
+ )
22
+
16
23
type (
17
24
TokenResponse struct {
18
25
Token string `json:"token"`
@@ -27,6 +34,30 @@ type (
27
34
}
28
35
)
29
36
37
+ type CookieContents struct {
38
+ Token string
39
+ ExpiresAt time.Time
40
+ Remember bool
41
+ }
42
+
43
+ func GetCookies (r * http.Request ) (* CookieContents , error ) {
44
+ cookie , err := r .Cookie (cookieNameToken )
45
+ if err != nil {
46
+ return nil , errors .New ("authorization cookie is required" )
47
+ }
48
+
49
+ rememberCookie , err := r .Cookie (cookieNameRemember )
50
+ if err != nil {
51
+ return nil , errors .New ("remember cookie is required" )
52
+ }
53
+
54
+ return & CookieContents {
55
+ Token : cookie .Value ,
56
+ ExpiresAt : cookie .Expires ,
57
+ Remember : rememberCookie .Value == "true" ,
58
+ }, nil
59
+ }
60
+
30
61
// HandleAuthLogin godoc
31
62
//
32
63
// @Summary User Login
@@ -81,6 +112,7 @@ func (ctrl *V1Controller) HandleAuthLogin() errchain.HandlerFunc {
81
112
return validate .NewRequestError (errors .New ("authentication failed" ), http .StatusInternalServerError )
82
113
}
83
114
115
+ ctrl .setCookies (w , noPort (r .Host ), newToken .Raw , newToken .ExpiresAt , loginForm .StayLoggedIn )
84
116
return server .JSON (w , http .StatusOK , TokenResponse {
85
117
Token : "Bearer " + newToken .Raw ,
86
118
ExpiresAt : newToken .ExpiresAt ,
@@ -108,6 +140,7 @@ func (ctrl *V1Controller) HandleAuthLogout() errchain.HandlerFunc {
108
140
return validate .NewRequestError (err , http .StatusInternalServerError )
109
141
}
110
142
143
+ ctrl .unsetCookies (w , noPort (r .Host ))
111
144
return server .JSON (w , http .StatusNoContent , nil )
112
145
}
113
146
}
@@ -133,6 +166,78 @@ func (ctrl *V1Controller) HandleAuthRefresh() errchain.HandlerFunc {
133
166
return validate .NewUnauthorizedError ()
134
167
}
135
168
169
+ ctrl .setCookies (w , noPort (r .Host ), newToken .Raw , newToken .ExpiresAt , false )
136
170
return server .JSON (w , http .StatusOK , newToken )
137
171
}
138
172
}
173
+
174
+ func noPort (host string ) string {
175
+ return strings .Split (host , ":" )[0 ]
176
+ }
177
+
178
+ func (ctrl * V1Controller ) setCookies (w http.ResponseWriter , domain , token string , expires time.Time , remember bool ) {
179
+ http .SetCookie (w , & http.Cookie {
180
+ Name : cookieNameRemember ,
181
+ Value : strconv .FormatBool (remember ),
182
+ Expires : expires ,
183
+ Domain : domain ,
184
+ Secure : ctrl .cookieSecure ,
185
+ HttpOnly : true ,
186
+ Path : "/" ,
187
+ })
188
+
189
+ // Set HTTP only cookie
190
+ http .SetCookie (w , & http.Cookie {
191
+ Name : cookieNameToken ,
192
+ Value : token ,
193
+ Expires : expires ,
194
+ Domain : domain ,
195
+ Secure : ctrl .cookieSecure ,
196
+ HttpOnly : true ,
197
+ Path : "/" ,
198
+ })
199
+
200
+ // Set Fake Session cookie
201
+ http .SetCookie (w , & http.Cookie {
202
+ Name : cookieNameSession ,
203
+ Value : "true" ,
204
+ Expires : expires ,
205
+ Domain : domain ,
206
+ Secure : ctrl .cookieSecure ,
207
+ HttpOnly : false ,
208
+ Path : "/" ,
209
+ })
210
+ }
211
+
212
+ func (ctrl * V1Controller ) unsetCookies (w http.ResponseWriter , domain string ) {
213
+ http .SetCookie (w , & http.Cookie {
214
+ Name : cookieNameToken ,
215
+ Value : "" ,
216
+ Expires : time .Unix (0 , 0 ),
217
+ Domain : domain ,
218
+ Secure : ctrl .cookieSecure ,
219
+ HttpOnly : true ,
220
+ Path : "/" ,
221
+ })
222
+
223
+ http .SetCookie (w , & http.Cookie {
224
+ Name : cookieNameRemember ,
225
+ Value : "false" ,
226
+ Expires : time .Unix (0 , 0 ),
227
+ Domain : domain ,
228
+ Secure : ctrl .cookieSecure ,
229
+ HttpOnly : true ,
230
+ Path : "/" ,
231
+ })
232
+
233
+ // Set Fake Session cookie
234
+ http .SetCookie (w , & http.Cookie {
235
+ Name : cookieNameSession ,
236
+ Value : "false" ,
237
+ Expires : time .Unix (0 , 0 ),
238
+ Domain : domain ,
239
+ Secure : ctrl .cookieSecure ,
240
+ HttpOnly : false ,
241
+ Path : "/" ,
242
+ })
243
+ }
0 commit comments