Skip to content

Commit

Permalink
refactor(auth): remove refresh token expiration handling
Browse files Browse the repository at this point in the history
- Remove handling of refresh token expiration as Casdoor never returns
`refresh_expires_in`[^1].
- Treat refresh tokens as always valid as they are renewed with each
access token refresh[^2].
- Return `401 Unauthorized` instead of `500 Internal Server Error` when
JWT parsing fails.

[^1]: https://github.com/casdoor/casdoor/blob/6f1f93725e77c8288aa0ac1c0d996feff906ddcf/object/token_oauth.go#L383-L390
[^2]: https://github.com/casdoor/casdoor/blob/6f1f93725e77c8288aa0ac1c0d996feff906ddcf/object/token_oauth.go#L351-L376

Signed-off-by: Aofei Sheng <aofei@aofeisheng.com>
  • Loading branch information
aofei committed Oct 18, 2024
1 parent 0050905 commit f620485
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 25 deletions.
2 changes: 1 addition & 1 deletion spx-backend/internal/controller/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func ensureUser(ctx context.Context, expectedUserID int64) (*model.User, error)
func (ctrl *Controller) UserFromToken(ctx context.Context, token string) (*model.User, error) {
claims, err := ctrl.casdoorClient.ParseJwtToken(token)
if err != nil {
return nil, fmt.Errorf("ctrl.casdoorClient.ParseJwtToken failed: %w", err)
return nil, fmt.Errorf("ctrl.casdoorClient.ParseJwtToken failed: %w: %w", ErrUnauthorized, err)
}
mUser, err := model.FirstOrCreateUser(ctx, ctrl.db, claims.Name)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion spx-backend/internal/controller/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func TestControllerUserFromToken(t *testing.T) {

_, err := ctrl.UserFromToken(context.Background(), "invalid-token")
require.Error(t, err)
assert.EqualError(t, err, "ctrl.casdoorClient.ParseJwtToken failed: token contains an invalid number of segments")
assert.EqualError(t, err, "ctrl.casdoorClient.ParseJwtToken failed: unauthorized: token contains an invalid number of segments")
})
}

Expand Down
31 changes: 8 additions & 23 deletions spx-gui/src/stores/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ export interface UserInfo {

interface TokenResponse {
access_token: string
refresh_token: string
expires_in: number
refresh_expires_in: number
refresh_token: string
}

const casdoorAuthRedirectPath = '/callback'
Expand All @@ -28,11 +27,8 @@ const tokenExpiryDelta = 60 * 1000 // 1 minute in milliseconds
export const useUserStore = defineStore('spx-user', {
state: () => ({
accessToken: null as string | null,
refreshToken: null as string | null,

// timestamp in milliseconds, null if never expires
accessTokenExpiresAt: null as number | null,
refreshTokenExpiresAt: null as number | null
accessTokenExpiresAt: null as number | null, // timestamp in milliseconds, null if never expires
refreshToken: null as string | null
}),
getters: {
isAccessTokenValid(): boolean {
Expand All @@ -42,15 +38,8 @@ export const useUserStore = defineStore('spx-user', {
this.accessTokenExpiresAt - tokenExpiryDelta > Date.now())
)
},
isRefreshTokenValid(): boolean {
return !!(
this.refreshToken &&
(this.refreshTokenExpiresAt === null ||
this.refreshTokenExpiresAt - tokenExpiryDelta > Date.now())
)
},
isSignedIn(): boolean {
return this.isAccessTokenValid || this.isRefreshTokenValid
return this.isAccessTokenValid
},
userInfo(): UserInfo | null {
if (!this.isSignedIn) return null
Expand All @@ -74,16 +63,15 @@ export const useUserStore = defineStore('spx-user', {
},
signOut() {
this.accessToken = null
this.refreshToken = null
this.accessTokenExpiresAt = null
this.refreshTokenExpiresAt = null
this.refreshToken = null
},
async ensureAccessToken(): Promise<string | null> {
if (this.isAccessTokenValid) return this.accessToken

if (this.isRefreshTokenValid) {
if (this.refreshToken != null) {
try {
const resp = await casdoorSdk.refreshAccessToken(this.refreshToken!)
const resp = await casdoorSdk.refreshAccessToken(this.refreshToken)
this.handleTokenResponse(resp)
} catch (e) {
console.error('failed to refresh access token', e)
Expand All @@ -101,11 +89,8 @@ export const useUserStore = defineStore('spx-user', {
},
handleTokenResponse(resp: TokenResponse) {
this.accessToken = resp.access_token
this.refreshToken = resp.refresh_token
this.accessTokenExpiresAt = resp.expires_in ? Date.now() + resp.expires_in * 1000 : null
this.refreshTokenExpiresAt = resp.refresh_expires_in
? Date.now() + resp.refresh_expires_in * 1000
: null
this.refreshToken = resp.refresh_token
}
},
persist: true
Expand Down

0 comments on commit f620485

Please sign in to comment.