Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
ae1e2293
Commit
ae1e2293
authored
Sep 20, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: auto remove current access token when sign out
parent
a60d4dee
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
58 additions
and
54 deletions
+58
-54
auth.go
api/v1/auth.go
+30
-4
jwt.go
api/v1/jwt.go
+28
-34
acl.go
api/v2/acl.go
+0
-16
No files found.
api/v1/auth.go
View file @
ae1e2293
...
@@ -251,8 +251,34 @@ func (s *APIV1Service) SignInSSO(c echo.Context) error {
...
@@ -251,8 +251,34 @@ func (s *APIV1Service) SignInSSO(c echo.Context) error {
// @Produce json
// @Produce json
// @Success 200 {boolean} true "Sign-out success"
// @Success 200 {boolean} true "Sign-out success"
// @Router /api/v1/auth/signout [POST]
// @Router /api/v1/auth/signout [POST]
func
(
*
APIV1Service
)
SignOut
(
c
echo
.
Context
)
error
{
func
(
s
*
APIV1Service
)
SignOut
(
c
echo
.
Context
)
error
{
RemoveTokensAndCookies
(
c
)
ctx
:=
c
.
Request
()
.
Context
()
accessToken
:=
findAccessToken
(
c
)
userID
,
_
:=
getUserIDFromAccessToken
(
accessToken
,
s
.
Secret
)
userAccessTokens
,
err
:=
s
.
Store
.
GetUserAccessTokens
(
ctx
,
userID
)
// Auto remove the current access token from the user access tokens.
if
err
==
nil
&&
len
(
userAccessTokens
)
!=
0
{
accessTokens
:=
[]
*
storepb
.
AccessTokensUserSetting_AccessToken
{}
for
_
,
userAccessToken
:=
range
userAccessTokens
{
if
accessToken
!=
userAccessToken
.
AccessToken
{
accessTokens
=
append
(
accessTokens
,
userAccessToken
)
}
}
if
_
,
err
:=
s
.
Store
.
UpsertUserSettingV1
(
ctx
,
&
storepb
.
UserSetting
{
UserId
:
userID
,
Key
:
storepb
.
UserSettingKey_USER_SETTING_ACCESS_TOKENS
,
Value
:
&
storepb
.
UserSetting_AccessTokens
{
AccessTokens
:
&
storepb
.
AccessTokensUserSetting
{
AccessTokens
:
accessTokens
,
},
},
});
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
fmt
.
Sprintf
(
"failed to upsert user setting, err: %s"
,
err
))
.
SetInternal
(
err
)
}
}
removeAccessTokenAndCookies
(
c
)
return
c
.
JSON
(
http
.
StatusOK
,
true
)
return
c
.
JSON
(
http
.
StatusOK
,
true
)
}
}
...
@@ -411,8 +437,8 @@ func (s *APIV1Service) createAuthSignUpActivity(c echo.Context, user *store.User
...
@@ -411,8 +437,8 @@ func (s *APIV1Service) createAuthSignUpActivity(c echo.Context, user *store.User
return
err
return
err
}
}
//
RemoveTokens
AndCookies removes the jwt token from the cookies.
//
removeAccessToken
AndCookies removes the jwt token from the cookies.
func
RemoveTokens
AndCookies
(
c
echo
.
Context
)
{
func
removeAccessToken
AndCookies
(
c
echo
.
Context
)
{
cookieExp
:=
time
.
Now
()
.
Add
(
-
1
*
time
.
Hour
)
cookieExp
:=
time
.
Now
()
.
Add
(
-
1
*
time
.
Hour
)
setTokenCookie
(
c
,
auth
.
AccessTokenCookieName
,
""
,
cookieExp
)
setTokenCookie
(
c
,
auth
.
AccessTokenCookieName
,
""
,
cookieExp
)
}
}
...
...
api/v1/jwt.go
View file @
ae1e2293
...
@@ -48,15 +48,6 @@ func findAccessToken(c echo.Context) string {
...
@@ -48,15 +48,6 @@ func findAccessToken(c echo.Context) string {
return
accessToken
return
accessToken
}
}
func
audienceContains
(
audience
jwt
.
ClaimStrings
,
token
string
)
bool
{
for
_
,
v
:=
range
audience
{
if
v
==
token
{
return
true
}
}
return
false
}
// JWTMiddleware validates the access token.
// JWTMiddleware validates the access token.
func
JWTMiddleware
(
server
*
APIV1Service
,
next
echo
.
HandlerFunc
,
secret
string
)
echo
.
HandlerFunc
{
func
JWTMiddleware
(
server
*
APIV1Service
,
next
echo
.
HandlerFunc
,
secret
string
)
echo
.
HandlerFunc
{
return
func
(
c
echo
.
Context
)
error
{
return
func
(
c
echo
.
Context
)
error
{
...
@@ -86,31 +77,10 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
...
@@ -86,31 +77,10 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Missing access token"
)
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Missing access token"
)
}
}
claims
:=
&
auth
.
ClaimsMessage
{}
userID
,
err
:=
getUserIDFromAccessToken
(
accessToken
,
secret
)
_
,
err
:=
jwt
.
ParseWithClaims
(
accessToken
,
claims
,
func
(
t
*
jwt
.
Token
)
(
any
,
error
)
{
if
t
.
Method
.
Alg
()
!=
jwt
.
SigningMethodHS256
.
Name
{
return
nil
,
errors
.
Errorf
(
"unexpected access token signing method=%v, expect %v"
,
t
.
Header
[
"alg"
],
jwt
.
SigningMethodHS256
)
}
if
kid
,
ok
:=
t
.
Header
[
"kid"
]
.
(
string
);
ok
{
if
kid
==
"v1"
{
return
[]
byte
(
secret
),
nil
}
}
return
nil
,
errors
.
Errorf
(
"unexpected access token kid=%v"
,
t
.
Header
[
"kid"
])
})
if
err
!=
nil
{
if
err
!=
nil
{
RemoveTokensAndCookies
(
c
)
removeAccessTokenAndCookies
(
c
)
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
errors
.
Wrap
(
err
,
"Invalid or expired access token"
))
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Invalid or expired access token"
)
}
if
!
audienceContains
(
claims
.
Audience
,
auth
.
AccessTokenAudienceName
)
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
fmt
.
Sprintf
(
"Invalid access token, audience mismatch, got %q, expected %q."
,
claims
.
Audience
,
auth
.
AccessTokenAudienceName
))
}
// We either have a valid access token or we will attempt to generate new access token.
userID
,
err
:=
util
.
ConvertStringToInt32
(
claims
.
Subject
)
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Malformed ID in the token."
)
}
}
accessTokens
,
err
:=
server
.
Store
.
GetUserAccessTokens
(
ctx
,
userID
)
accessTokens
,
err
:=
server
.
Store
.
GetUserAccessTokens
(
ctx
,
userID
)
...
@@ -118,7 +88,7 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
...
@@ -118,7 +88,7 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to get user access tokens."
)
.
WithInternal
(
err
)
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to get user access tokens."
)
.
WithInternal
(
err
)
}
}
if
!
validateAccessToken
(
accessToken
,
accessTokens
)
{
if
!
validateAccessToken
(
accessToken
,
accessTokens
)
{
RemoveTokens
AndCookies
(
c
)
removeAccessToken
AndCookies
(
c
)
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Invalid access token."
)
return
echo
.
NewHTTPError
(
http
.
StatusUnauthorized
,
"Invalid access token."
)
}
}
...
@@ -139,6 +109,30 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
...
@@ -139,6 +109,30 @@ func JWTMiddleware(server *APIV1Service, next echo.HandlerFunc, secret string) e
}
}
}
}
func
getUserIDFromAccessToken
(
accessToken
,
secret
string
)
(
int32
,
error
)
{
claims
:=
&
auth
.
ClaimsMessage
{}
_
,
err
:=
jwt
.
ParseWithClaims
(
accessToken
,
claims
,
func
(
t
*
jwt
.
Token
)
(
any
,
error
)
{
if
t
.
Method
.
Alg
()
!=
jwt
.
SigningMethodHS256
.
Name
{
return
nil
,
errors
.
Errorf
(
"unexpected access token signing method=%v, expect %v"
,
t
.
Header
[
"alg"
],
jwt
.
SigningMethodHS256
)
}
if
kid
,
ok
:=
t
.
Header
[
"kid"
]
.
(
string
);
ok
{
if
kid
==
"v1"
{
return
[]
byte
(
secret
),
nil
}
}
return
nil
,
errors
.
Errorf
(
"unexpected access token kid=%v"
,
t
.
Header
[
"kid"
])
})
if
err
!=
nil
{
return
0
,
errors
.
Wrap
(
err
,
"Invalid or expired access token"
)
}
// We either have a valid access token or we will attempt to generate new access token.
userID
,
err
:=
util
.
ConvertStringToInt32
(
claims
.
Subject
)
if
err
!=
nil
{
return
0
,
errors
.
Wrap
(
err
,
"Malformed ID in the token"
)
}
return
userID
,
nil
}
func
(
*
APIV1Service
)
defaultAuthSkipper
(
c
echo
.
Context
)
bool
{
func
(
*
APIV1Service
)
defaultAuthSkipper
(
c
echo
.
Context
)
bool
{
path
:=
c
.
Path
()
path
:=
c
.
Path
()
return
util
.
HasPrefixes
(
path
,
"/api/v1/auth"
)
return
util
.
HasPrefixes
(
path
,
"/api/v1/auth"
)
...
...
api/v2/acl.go
View file @
ae1e2293
...
@@ -96,13 +96,6 @@ func (in *GRPCAuthInterceptor) authenticate(ctx context.Context, accessToken str
...
@@ -96,13 +96,6 @@ func (in *GRPCAuthInterceptor) authenticate(ctx context.Context, accessToken str
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
status
.
Errorf
(
codes
.
Unauthenticated
,
"Invalid or expired access token"
)
return
""
,
status
.
Errorf
(
codes
.
Unauthenticated
,
"Invalid or expired access token"
)
}
}
if
!
audienceContains
(
claims
.
Audience
,
auth
.
AccessTokenAudienceName
)
{
return
""
,
status
.
Errorf
(
codes
.
Unauthenticated
,
"invalid access token, audience mismatch, got %q, expected %q. you may send request to the wrong environment"
,
claims
.
Audience
,
auth
.
AccessTokenAudienceName
,
)
}
// We either have a valid access token or we will attempt to generate new access token.
// We either have a valid access token or we will attempt to generate new access token.
userID
,
err
:=
util
.
ConvertStringToInt32
(
claims
.
Subject
)
userID
,
err
:=
util
.
ConvertStringToInt32
(
claims
.
Subject
)
...
@@ -155,15 +148,6 @@ func getTokenFromMetadata(md metadata.MD) (string, error) {
...
@@ -155,15 +148,6 @@ func getTokenFromMetadata(md metadata.MD) (string, error) {
return
accessToken
,
nil
return
accessToken
,
nil
}
}
func
audienceContains
(
audience
jwt
.
ClaimStrings
,
token
string
)
bool
{
for
_
,
v
:=
range
audience
{
if
v
==
token
{
return
true
}
}
return
false
}
func
validateAccessToken
(
accessTokenString
string
,
userAccessTokens
[]
*
storepb
.
AccessTokensUserSetting_AccessToken
)
bool
{
func
validateAccessToken
(
accessTokenString
string
,
userAccessTokens
[]
*
storepb
.
AccessTokensUserSetting_AccessToken
)
bool
{
for
_
,
userAccessToken
:=
range
userAccessTokens
{
for
_
,
userAccessToken
:=
range
userAccessTokens
{
if
accessTokenString
==
userAccessToken
.
AccessToken
{
if
accessTokenString
==
userAccessToken
.
AccessToken
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment