support clear token in database after logout, support clear browser token when api responses token invalid
This commit is contained in:
@@ -118,6 +118,9 @@ func startWebServer(c *cli.Context) error {
|
||||
apiV1Route := apiRoute.Group("/v1")
|
||||
apiV1Route.Use(bindMiddleware(middlewares.JWTAuthorization))
|
||||
{
|
||||
// Logout
|
||||
apiV1Route.GET("/logout.json", bindApi(api.Tokens.TokenRevokeCurrentHandler))
|
||||
|
||||
// Tokens
|
||||
apiV1Route.GET("/tokens/list.json", bindApi(api.Tokens.TokenListHandler))
|
||||
apiV1Route.POST("/tokens/revoke.json", bindApi(api.Tokens.TokenRevokeHandler))
|
||||
|
||||
@@ -53,6 +53,34 @@ func (a *TokensApi) TokenListHandler(c *core.Context) (interface{}, *errs.Error)
|
||||
return tokenResps, nil
|
||||
}
|
||||
|
||||
func (a *TokensApi) TokenRevokeCurrentHandler(c *core.Context) (interface{}, *errs.Error) {
|
||||
claims := c.GetTokenClaims()
|
||||
uid := c.GetCurrentUid()
|
||||
userTokenId, err := utils.StringToInt64(claims.UserTokenId)
|
||||
|
||||
if err != nil {
|
||||
log.WarnfWithRequestId(c, "[tokens.TokenRevokeCurrentHandler] parse user token id failed, because %s", err.Error())
|
||||
return nil, errs.NewIncompleteOrIncorrectSubmissionError(err)
|
||||
}
|
||||
|
||||
tokenRecord := &models.TokenRecord{
|
||||
Uid: uid,
|
||||
UserTokenId: userTokenId,
|
||||
CreatedUnixTime: claims.IssuedAt,
|
||||
}
|
||||
|
||||
tokenId := a.tokens.GenerateTokenId(tokenRecord)
|
||||
err = a.tokens.DeleteToken(tokenRecord)
|
||||
|
||||
if err != nil {
|
||||
log.ErrorfWithRequestId(c, "[token.TokenRevokeCurrentHandler] failed to revoke token \"id:%s\" for user \"uid:%d\", because %s", tokenId, uid, err.Error())
|
||||
return nil, errs.Or(err, errs.ErrOperationFailed)
|
||||
}
|
||||
|
||||
log.InfofWithRequestId(c, "[token.TokenRevokeCurrentHandler] user \"uid:%d\" has revoked token \"id:%s\"", uid, tokenId)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (a *TokensApi) TokenRevokeHandler(c *core.Context) (interface{}, *errs.Error) {
|
||||
var tokenRevokeReq models.TokenRevokeRequest
|
||||
err := c.ShouldBindJSON(&tokenRevokeReq)
|
||||
|
||||
@@ -17,6 +17,16 @@ axios.interceptors.request.use(config => {
|
||||
axios.interceptors.response.use(response => {
|
||||
return response;
|
||||
}, error => {
|
||||
if (error.response && error.response.data && error.response.data.errorCode) {
|
||||
const errorCode = error.response.data.errorCode;
|
||||
|
||||
if (202001 <= errorCode && errorCode <= 202007) { // unauthorized access or token is invalid
|
||||
userState.clearToken();
|
||||
location.reload();
|
||||
return Promise.reject({ processed: true });
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
@@ -38,5 +48,8 @@ export default {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
},
|
||||
logout: () => {
|
||||
return axios.get('v1/logout.json');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,6 +5,15 @@ export default {
|
||||
}
|
||||
},
|
||||
'error': {
|
||||
'unauthorized access': 'Unauthorized access',
|
||||
'token is expired': 'Token is expired',
|
||||
'token is invalid': 'Token is invalid',
|
||||
'user token id is invalid': 'User token id is invalid',
|
||||
'token id is invalid': 'Token id is invalid',
|
||||
'token is not found': 'Token is not found',
|
||||
'token type is invalid': 'Token type is invalid',
|
||||
'token requires two factor authorization': 'Token requires two factor authorization',
|
||||
'token does not require two factor authorization': 'Token does not require two factor authorization',
|
||||
'user id is invalid': 'User id is invalid',
|
||||
'username is empty': 'Username is empty',
|
||||
'email is empty': 'Email is empty',
|
||||
@@ -51,4 +60,5 @@ export default {
|
||||
'Language': 'Language',
|
||||
'Log Out': 'Log Out',
|
||||
'Are you sure you want to log out?': 'Are you sure you want to log out?',
|
||||
'Unable to logout': 'Unable to logout',
|
||||
};
|
||||
|
||||
@@ -5,6 +5,15 @@ export default {
|
||||
}
|
||||
},
|
||||
'error': {
|
||||
'unauthorized access': '未授权的登录',
|
||||
'token is expired': '认证令牌已过期',
|
||||
'token is invalid': '认证令牌无效',
|
||||
'user token id is invalid': '用户认证令牌ID无效',
|
||||
'token id is invalid': '认证令牌ID无效',
|
||||
'token is not found': '认证令牌不存在',
|
||||
'token type is invalid': '认证令牌类型无效',
|
||||
'token requires two factor authorization': '认证令牌需要两步验证',
|
||||
'token does not require two factor authorization': '认证令牌不需要两步验证',
|
||||
'user id is invalid': '用户ID无效',
|
||||
'username is empty': '用户名为空',
|
||||
'email is empty': '电子邮箱为空',
|
||||
@@ -51,4 +60,5 @@ export default {
|
||||
'Language': '语言',
|
||||
'Log Out': '退出登录',
|
||||
'Are you sure you want to log out?': '您确定是否要退出登录?',
|
||||
'Unable to logout': '无法退出登录',
|
||||
};
|
||||
|
||||
@@ -137,7 +137,7 @@ export default {
|
||||
password: self.password
|
||||
}).then(response => {
|
||||
hasResponse = true;
|
||||
self.$f7.preloader.hide();
|
||||
app.preloader.hide();
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result || !data.result.token) {
|
||||
@@ -155,14 +155,18 @@ export default {
|
||||
router.navigate('/');
|
||||
}).catch(error => {
|
||||
hasResponse = true;
|
||||
self.$f7.preloader.hide();
|
||||
app.preloader.hide();
|
||||
|
||||
if (error && error.processed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||
self.$alert(`error.${error.response.data.errorMessage}`);
|
||||
} else {
|
||||
self.$alert('Unable to login');
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
verify() {
|
||||
const self = this;
|
||||
|
||||
@@ -38,11 +38,44 @@ export default {
|
||||
methods: {
|
||||
logout() {
|
||||
const self = this;
|
||||
const app = self.$f7;
|
||||
const router = self.$f7router;
|
||||
|
||||
self.$confirm('Are you sure you want to log out?', () => {
|
||||
self.$user.clearToken();
|
||||
router.navigate('/');
|
||||
let hasResponse = false;
|
||||
|
||||
setTimeout(() => {
|
||||
if (!hasResponse) {
|
||||
app.preloader.show();
|
||||
}
|
||||
}, 200);
|
||||
|
||||
self.$services.logout().then(response => {
|
||||
hasResponse = true;
|
||||
app.preloader.hide();
|
||||
const data = response.data;
|
||||
|
||||
if (!data || !data.success || !data.result) {
|
||||
self.$alert('Unable to logout');
|
||||
return;
|
||||
}
|
||||
|
||||
self.$user.clearToken();
|
||||
router.navigate('/');
|
||||
}).catch(error => {
|
||||
hasResponse = true;
|
||||
app.preloader.hide();
|
||||
|
||||
if (error && error.processed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error.response && error.response.data && error.response.data.errorMessage) {
|
||||
self.$alert(`error.${error.response.data.errorMessage}`);
|
||||
} else {
|
||||
self.$alert('Unable to logout');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user