@@ -6,24 +6,63 @@ import (
6
6
"github.com/ProtocolONE/authone-jwt-verifier-golang"
7
7
"github.com/ProtocolONE/authone-jwt-verifier-golang/example/nocache"
8
8
jwt_middleware "github.com/ProtocolONE/authone-jwt-verifier-golang/middleware/echo"
9
- "github.com/labstack/echo"
10
- "github.com/labstack/echo/middleware"
9
+ "github.com/labstack/echo/v4 "
10
+ "github.com/labstack/echo/v4/ middleware"
11
11
"github.com/labstack/gommon/log"
12
+ "html/template"
13
+ "io"
12
14
"net/http"
15
+ "time"
13
16
)
14
17
15
18
var (
16
- clientID = "5c77953f51c0950001436152"
17
- clientSecret = "tGtL8HcRDY5X7VxEhyIye2EhiN9YyTJ5Ny0AndLNXQFgKCSgUKE0Ti4X9fHK6Qib"
18
- scopes = []string {"openid" , "offline" }
19
- responseType = "code"
20
- redirectURL = "http://127.0.0.1:1323/auth/callback"
21
- authDomain = "https://auth1.tst.protocol.one"
22
- jwtv * jwtverifier.JwtVerifier
19
+ //clientID = "5c7fd8c50dd75d000162c69f"
20
+ clientID = "5c935c8e02429c5c98920f2c"
21
+ //clientSecret = "TVzu97mMqsn4bRQbgS07MdIuf3TMgZHEm0fjKWWP5DvzppyTtXA8sgQtqazr91zq"
22
+ clientSecret = "BxupC6l655Y3gnFQxfxME4IvLvDpKYwbfRp9ri07zxnPzFaLraCgvLkrzh0618Rt"
23
+ scopes = []string {"openid" , "offline" }
24
+ redirectURL = "http://localhost:1323/auth/callback"
25
+ logoutRedirectUri = "http://127.0.0.1:1323/logout_result"
26
+ authDomain = "http://127.0.0.1:8080"
27
+ jwtv * jwtverifier.JwtVerifier
23
28
)
24
29
30
+ type payload struct {
31
+ ClientID string `json:"client_id"`
32
+ Result bool `json:"result"`
33
+ Error string `json:"error"`
34
+ AccessToken string `json:"access_token"`
35
+ RefreshToken string `json:"refresh_token"`
36
+ Expire time.Time `json:"expire"`
37
+ IntrospectAccessToken jwtverifier.IntrospectToken `json:"introspect_access_token"`
38
+ IntrospectRefreshToken jwtverifier.IntrospectToken `json:"introspect_refresh_token"`
39
+ UserInfo jwtverifier.UserInfo `json:"user_info"`
40
+ IdToken jwtverifier.IdToken `json:"id_token"`
41
+ }
42
+
43
+ type Object struct {
44
+ Identifier string
45
+ }
46
+
47
+ type Template struct {
48
+ templates * template.Template
49
+ }
50
+
51
+ var (
52
+ authCookieName = "auth1_access_token"
53
+ obj = & Object {}
54
+ )
55
+
56
+ func (t * Template ) Render (w io.Writer , name string , data interface {}, ctx echo.Context ) error {
57
+ return t .templates .ExecuteTemplate (w , name , data )
58
+ }
59
+
25
60
func main () {
61
+ t := & Template {
62
+ templates : template .Must (template .ParseGlob ("templates/*.html" )),
63
+ }
26
64
e := echo .New ()
65
+ e .Renderer = t
27
66
e .Logger .SetLevel (log .ERROR )
28
67
e .Use (middleware .Logger ())
29
68
e .Use (nocache .NoCache ())
@@ -37,23 +76,52 @@ func main() {
37
76
}
38
77
jwtv = jwtverifier .NewJwtVerifier (settings )
39
78
40
- // Routes
79
+ f := func (ui * jwtverifier.UserInfo ) {
80
+ obj .Identifier = string (ui .UserID )
81
+ }
82
+
83
+ // Main page with login|logout actions
41
84
e .GET ("/" , index )
42
85
// Create state and redirect to auth endpoint
43
86
e .GET ("/authme" , authMeProcess )
44
87
// Validate auth code result
45
88
e .GET ("/auth/callback" , authCallback )
46
- // Validate auth header
89
+ // Check access to page by authentication header
47
90
e .GET ("/private" , privateZone , jwt_middleware .AuthOneJwtWithConfig (jwtv ))
48
- // Routes
91
+ // Check access to page by authentication header with custom callable function
92
+ e .GET ("/private_callable" , privateZoneCallable , jwt_middleware .AuthOneJwtCallableWithConfig (jwtv , f ))
93
+ // Page without authentication header validation
49
94
e .GET ("/some-route" , someRoute )
95
+ // Logout
96
+ e .GET ("/logout" , logout )
97
+ // Logout callback for clean local tokens, session and etc.
98
+ e .GET ("/logout_result" , logoutResult )
50
99
51
100
// Start server
52
101
e .Logger .Fatal (e .Start (":1323" ))
53
102
}
54
103
55
104
func index (c echo.Context ) error {
56
- return c .HTML (http .StatusOK , "<a href=\" /authme\" >Auth me</a>" )
105
+ cookie , _ := c .Request ().Cookie (authCookieName )
106
+ isAuthenticate := cookie .String () != ""
107
+
108
+ if isAuthenticate == true {
109
+ userInfo , err := userinfo (c .Request ().Context (), cookie .Value )
110
+ if err != nil {
111
+ c .Echo ().Logger .Error ("Unable to get user info" )
112
+ fmt .Print (err )
113
+ } else {
114
+ fmt .Print (userInfo )
115
+ }
116
+ }
117
+
118
+ return c .Render (http .StatusOK , "index.html" , map [string ]interface {}{
119
+ "AuthDomain" : authDomain ,
120
+ "ClientID" : clientID ,
121
+ "RedirectUri" : redirectURL ,
122
+ "LogoutRedirectUri" : logoutRedirectUri ,
123
+ "IsAuthenticate" : isAuthenticate ,
124
+ })
57
125
}
58
126
59
127
func someRoute (c echo.Context ) error {
@@ -66,75 +134,128 @@ func privateZone(c echo.Context) error {
66
134
return c .HTML (http .StatusOK , "" )
67
135
}
68
136
137
+ func privateZoneCallable (c echo.Context ) error {
138
+ fmt .Printf ("User: %+v\n " , obj .Identifier )
139
+ return c .HTML (http .StatusOK , "" )
140
+ }
141
+
69
142
func authMeProcess (c echo.Context ) error {
70
143
options := jwtverifier.AuthUrlOption {
71
- Key : "state " ,
72
- Value : "example_state_string " ,
144
+ Key : "test1 " ,
145
+ Value : "value1 " ,
73
146
}
74
- url := jwtv .CreateAuthUrl (responseType , options )
75
- fmt .Printf ("%s\n " , url )
76
- return c .Redirect (http .StatusPermanentRedirect , url )
147
+ u := jwtv .CreateAuthUrl ("example_state_string" , options )
148
+ return c .Redirect (http .StatusPermanentRedirect , u )
149
+ }
150
+
151
+ func logout (c echo.Context ) error {
152
+ c .SetCookie (& http.Cookie {Name : authCookieName , Value : "" , Path : "/" , Expires : time .Unix (0 , 0 )})
153
+ url := fmt .Sprintf ("%s://%s" , c .Scheme (), c .Request ().Host )
154
+ return c .Redirect (http .StatusPermanentRedirect , jwtv .CreateLogoutUrl (url ))
155
+ }
156
+
157
+ func logoutResult (c echo.Context ) error {
158
+ c .SetCookie (& http.Cookie {Name : authCookieName , Value : "" , Path : "/" , Expires : time .Unix (0 , 0 )})
159
+ return c .Render (http .StatusOK , "logout.html" , map [string ]interface {}{})
77
160
}
78
161
79
162
func authCallback (c echo.Context ) error {
163
+ payload := & payload {ClientID : clientID , Result : true }
80
164
ctx := c .Request ().Context ()
81
165
t , err := jwtv .Exchange (ctx , fmt .Sprint (c .QueryParam ("code" )))
82
166
if err != nil {
83
167
c .Echo ().Logger .Error ("Unable to get auth token" )
84
- return c . HTML ( http . StatusBadRequest , "Authorization error" )
85
- }
86
- fmt . Printf ( " AccessToken: %+v \n " , t . AccessToken )
168
+ payload . Error = fmt . Sprintf ( "Authorization error: %s \n " , err . Error () )
169
+ } else {
170
+ c . SetCookie ( & http. Cookie { Name : authCookieName , Value : t . AccessToken , Path : "/" , Expires : t . Expiry } )
87
171
88
- if err := introspect (ctx , t ); err != nil {
89
- c .Echo ().Logger .Error ("Unable to get introspect access token" )
90
- fmt .Print (err )
91
- return nil
92
- }
172
+ payload .AccessToken = t .AccessToken
173
+ payload .RefreshToken = t .RefreshToken
174
+ payload .Expire = t .Expiry
175
+ fmt .Printf ("AccessToken string: %s\n " , t .AccessToken )
176
+ fmt .Printf ("RefreshToken string: %s\n " , t .RefreshToken )
177
+ fmt .Printf ("Token expire: %s" , t .Expiry )
178
+
179
+ introspectAccessToken , introspectRefreshToken , err := introspect (ctx , t )
180
+ if err != nil {
181
+ c .Echo ().Logger .Error ("Unable to get introspect access token" )
182
+ fmt .Print (err )
183
+ payload .Error = fmt .Sprintf ("Unable to introspect token: %s\n " , err .Error ())
184
+ } else {
185
+ payload .IntrospectAccessToken = * introspectAccessToken
186
+ payload .IntrospectRefreshToken = * introspectRefreshToken
187
+ }
188
+
189
+ userInfo , err := userinfo (ctx , t .AccessToken )
190
+ if err != nil {
191
+ c .Echo ().Logger .Error ("Unable to get user info" )
192
+ fmt .Print (err )
193
+ payload .Error = fmt .Sprintf ("Unable to get user info: %s\n " , err .Error ())
194
+ } else {
195
+ payload .UserInfo = * userInfo
196
+ }
93
197
94
- if err := userinfo (ctx , t ); err != nil {
95
- c .Echo ().Logger .Error ("Unable to get user info" )
96
- fmt .Print (err )
97
- return nil
198
+ idToken , err := validateIdToken (ctx , t )
199
+ if err != nil {
200
+ c .Echo ().Logger .Error ("Unable to get validate id token" )
201
+ fmt .Print (err )
202
+ payload .Error = fmt .Sprintf ("Unable to validate id token: %s\n " , err .Error ())
203
+ } else {
204
+ payload .IdToken = * idToken
205
+ }
98
206
}
99
207
100
- if err := validateIdToken (ctx , t ); err != nil {
101
- c .Echo ().Logger .Error ("Unable to get validate id token" )
102
- fmt .Print (err )
103
- return nil
208
+ if payload .Error != "" {
209
+ payload .Result = false
104
210
}
105
211
106
- return nil
212
+ return c .Render (http .StatusOK , "callback.html" , map [string ]interface {}{
213
+ "Result" : payload .Result ,
214
+ "Error" : payload .Error ,
215
+ "AccessToken" : payload .AccessToken ,
216
+ "RefreshToken" : payload .RefreshToken ,
217
+ "Expire" : payload .Expire ,
218
+ })
107
219
}
108
220
109
- func introspect (c context.Context , token * jwtverifier.Token ) error {
110
- t , err := jwtv .Introspect (c , token .AccessToken )
221
+ func introspect (c context.Context , token * jwtverifier.Token ) ( * jwtverifier. IntrospectToken , * jwtverifier. IntrospectToken , error ) {
222
+ at , err := jwtv .Introspect (c , token .AccessToken )
111
223
if err != nil {
112
- return err
224
+ return nil , nil , err
113
225
}
114
- fmt .Printf ("JWT token: %+v\n " , t )
115
- fmt .Printf ("Expiry: %+v\n " , token .Expiry )
116
- return nil
226
+ fmt .Printf ("AccessToken JWT: %+v\n " , at )
227
+ fmt .Printf ("AccessToken expiry: %+v\n " , at .Exp )
228
+
229
+ rt , err := jwtv .Introspect (c , token .RefreshToken )
230
+ if err != nil {
231
+ return nil , nil , err
232
+ }
233
+ fmt .Printf ("RefreshToken JWT: %+v\n " , rt )
234
+ fmt .Printf ("RefreshToken expiry: %+v\n " , rt .Exp )
235
+
236
+ return at , rt , nil
117
237
}
118
238
119
- func userinfo (c context.Context , token * jwtverifier.Token ) error {
120
- info , err := jwtv .GetUserInfo (c , token . AccessToken )
239
+ func userinfo (c context.Context , token string ) ( * jwtverifier.UserInfo , error ) {
240
+ info , err := jwtv .GetUserInfo (c , token )
121
241
if err != nil {
122
- return err
242
+ return nil , err
123
243
}
124
244
fmt .Printf ("User info: %+v\n " , info )
125
- return nil
245
+ return info , nil
126
246
}
127
247
128
- func validateIdToken (c context.Context , token * jwtverifier.Token ) error {
248
+ func validateIdToken (c context.Context , token * jwtverifier.Token ) ( * jwtverifier. IdToken , error ) {
129
249
id := token .Extra ("id_token" )
130
250
if id == nil {
131
251
fmt .Print ("ID token is not required\n " )
132
- return nil
252
+ return nil , nil
133
253
}
254
+ fmt .Printf ("ID token string: %+v\n " , id )
134
255
t , err := jwtv .ValidateIdToken (c , fmt .Sprint (id ))
135
256
if err != nil {
136
- return err
257
+ return nil , err
137
258
}
138
259
fmt .Printf ("ID token: %+v\n " , t )
139
- return nil
260
+ return t , nil
140
261
}
0 commit comments