gitee token 过期后自动刷新处理

This commit is contained in:
xiaoqi.cxq 2022-05-26 13:13:18 +08:00
parent 3ee3cf6470
commit 0656045f67
2 changed files with 94 additions and 44 deletions

View File

@ -12,7 +12,6 @@ function giteeToken(clientId, code, oauth2RedirectUri) {
client_secret: conf.values.giteeClientSecret, client_secret: conf.values.giteeClientSecret,
code, code,
grant_type: 'authorization_code', grant_type: 'authorization_code',
scope: 'authorization_code',
redirect_uri: oauth2RedirectUri, redirect_uri: oauth2RedirectUri,
}, },
json: true json: true
@ -22,7 +21,7 @@ function giteeToken(clientId, code, oauth2RedirectUri) {
} }
const token = body.access_token; const token = body.access_token;
if (token) { if (token) {
resolve(token); resolve(body);
} else { } else {
reject(res.statusCode + ',body:' + JSON.stringify(body)); reject(res.statusCode + ',body:' + JSON.stringify(body));
} }
@ -33,7 +32,7 @@ function giteeToken(clientId, code, oauth2RedirectUri) {
exports.giteeToken = (req, res) => { exports.giteeToken = (req, res) => {
giteeToken(req.query.clientId, req.query.code, req.query.oauth2RedirectUri) giteeToken(req.query.clientId, req.query.code, req.query.oauth2RedirectUri)
.then( .then(
token => res.send(token), tokenBody => res.send(tokenBody),
err => res err => res
.status(400) .status(400)
.send(err ? err.message || err.toString() : 'bad_code'), .send(err ? err.message || err.toString() : 'bad_code'),

View File

@ -5,6 +5,8 @@ import userSvc from '../../userSvc';
import badgeSvc from '../../badgeSvc'; import badgeSvc from '../../badgeSvc';
import constants from '../../../data/constants'; import constants from '../../../data/constants';
const tokenExpirationMargin = 5 * 60 * 1000;
const request = (token, options) => networkSvc.request({ const request = (token, options) => networkSvc.request({
...options, ...options,
headers: { headers: {
@ -61,31 +63,42 @@ export default {
/** /**
* https://developer.gitee.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ * https://developer.gitee.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/
*/ */
async startOauth2(scopes, sub = null, silent = false) { async startOauth2(lastRefreshToken, silent = false) {
const clientId = store.getters['data/serverConf'].giteeClientId; const clientId = store.getters['data/serverConf'].giteeClientId;
let tokenBody;
// Get an OAuth2 code if (!silent) {
const { code } = await networkSvc.startOauth2( // Get an OAuth2 code
'https://gitee.com/oauth/authorize', const { code } = await networkSvc.startOauth2(
{ 'https://gitee.com/oauth/authorize',
client_id: clientId, {
scope: 'projects pull_requests', client_id: clientId,
response_type: 'code', scope: 'projects pull_requests',
}, response_type: 'code',
silent, },
); silent,
);
// Exchange code with token // Exchange code with token
const accessToken = (await networkSvc.request({ tokenBody = (await networkSvc.request({
method: 'GET', method: 'GET',
url: 'oauth2/giteeToken', url: 'oauth2/giteeToken',
params: { params: {
clientId, clientId,
code, code,
oauth2RedirectUri: constants.oauth2RedirectUri, oauth2RedirectUri: constants.oauth2RedirectUri,
}, },
})).body; })).body;
} else {
// grant_type=refresh_token&refresh_token={refresh_token}
tokenBody = (await networkSvc.request({
method: 'POST',
url: 'https://gitee.com/oauth/token',
params: {
grant_type: 'refresh_token',
refresh_token: lastRefreshToken,
},
})).body;
}
const accessToken = tokenBody.access_token;
// Call the user info endpoint // Call the user info endpoint
const user = (await networkSvc.request({ const user = (await networkSvc.request({
method: 'GET', method: 'GET',
@ -100,15 +113,11 @@ export default {
imageUrl: user.avatar_url || '', imageUrl: user.avatar_url || '',
}); });
// Check the returned sub consistency // Build token object including sub 在token失效后刷新token 如果刷新失败则触发重新授权
if (sub && `${user.login}` !== sub) {
throw new Error('Gitee account ID not expected.');
}
// Build token object including scopes and sub
const token = { const token = {
scopes,
accessToken, accessToken,
refreshToken: tokenBody.refresh_token,
expiresOn: Date.now() + (tokenBody.expires_in * 1000),
name: user.login, name: user.login,
sub: `${user.login}`, sub: `${user.login}`,
}; };
@ -117,6 +126,39 @@ export default {
store.dispatch('data/addGiteeToken', token); store.dispatch('data/addGiteeToken', token);
return token; return token;
}, },
// 刷新token
async refreshToken(token) {
const { sub } = token;
const lastToken = store.getters['data/giteeTokensBySub'][sub];
// 兼容旧的没有过期时间
if (!lastToken.expiresOn) {
await store.dispatch('modal/open', {
type: 'providerRedirection',
name: 'Gitee',
});
return this.startOauth2();
}
// lastToken is not expired
if (lastToken.expiresOn > Date.now() - tokenExpirationMargin) {
return lastToken;
}
// existing token is about to expire.
// Try to get a new token in background
try {
return await this.startOauth2(lastToken.refreshToken, true);
} catch (err) {
// If it fails try to popup a window
if (store.state.offline) {
throw err;
}
await store.dispatch('modal/open', {
type: 'providerRedirection',
name: 'Gitee',
});
return this.startOauth2();
}
},
async addAccount() { async addAccount() {
const token = await this.startOauth2(); const token = await this.startOauth2();
badgeSvc.addBadge('addGiteeAccount'); badgeSvc.addBadge('addGiteeAccount');
@ -133,10 +175,11 @@ export default {
repo, repo,
branch, branch,
}) { }) {
const { commit } = await repoRequest(token, owner, repo, { const refreshedToken = await this.refreshToken(token);
const { commit } = await repoRequest(refreshedToken, owner, repo, {
url: `commits/${encodeURIComponent(branch)}`, url: `commits/${encodeURIComponent(branch)}`,
}); });
const { tree, truncated } = await repoRequest(token, owner, repo, { const { tree, truncated } = await repoRequest(refreshedToken, owner, repo, {
url: `git/trees/${encodeURIComponent(commit.tree.sha)}?recursive=1`, url: `git/trees/${encodeURIComponent(commit.tree.sha)}?recursive=1`,
}); });
if (truncated) { if (truncated) {
@ -155,7 +198,8 @@ export default {
sha, sha,
path, path,
}) { }) {
return repoRequest(token, owner, repo, { const refreshedToken = await this.refreshToken(token);
return repoRequest(refreshedToken, owner, repo, {
url: 'commits', url: 'commits',
params: { sha, path }, params: { sha, path },
}); });
@ -174,7 +218,8 @@ export default {
content, content,
sha, sha,
}) { }) {
return repoRequest(token, owner, repo, { const refreshedToken = await this.refreshToken(token);
return repoRequest(refreshedToken, owner, repo, {
method: sha ? 'PUT' : 'POST', method: sha ? 'PUT' : 'POST',
url: `contents/${encodeURIComponent(path)}`, url: `contents/${encodeURIComponent(path)}`,
body: { body: {
@ -197,7 +242,8 @@ export default {
path, path,
sha, sha,
}) { }) {
return repoRequest(token, owner, repo, { const refreshedToken = await this.refreshToken(token);
return repoRequest(refreshedToken, owner, repo, {
method: 'DELETE', method: 'DELETE',
url: `contents/${encodeURIComponent(path)}`, url: `contents/${encodeURIComponent(path)}`,
body: { body: {
@ -218,7 +264,8 @@ export default {
branch, branch,
path, path,
}) { }) {
const { sha, content } = await repoRequest(token, owner, repo, { const refreshedToken = await this.refreshToken(token);
const { sha, content } = await repoRequest(refreshedToken, owner, repo, {
url: `contents/${encodeURIComponent(path)}`, url: `contents/${encodeURIComponent(path)}`,
params: { ref: branch }, params: { ref: branch },
}); });
@ -240,7 +287,8 @@ export default {
isPublic, isPublic,
gistId, gistId,
}) { }) {
const { body } = await request(token, gistId ? { const refreshedToken = await this.refreshToken(token);
const { body } = await request(refreshedToken, gistId ? {
method: 'PATCH', method: 'PATCH',
url: `https://gitee.com/api/v5/gists/${gistId}`, url: `https://gitee.com/api/v5/gists/${gistId}`,
body: { body: {
@ -275,7 +323,8 @@ export default {
gistId, gistId,
filename, filename,
}) { }) {
const result = (await request(token, { const refreshedToken = await this.refreshToken(token);
const result = (await request(refreshedToken, {
url: `https://gitee.com/api/v5/gists/${gistId}`, url: `https://gitee.com/api/v5/gists/${gistId}`,
})).body.files[filename]; })).body.files[filename];
if (!result) { if (!result) {
@ -291,7 +340,8 @@ export default {
token, token,
gistId, gistId,
}) { }) {
const { body } = await request(token, { const refreshedToken = await this.refreshToken(token);
const { body } = await request(refreshedToken, {
url: `https://gitee.com/api/v5/gists/${gistId}/commits`, url: `https://gitee.com/api/v5/gists/${gistId}/commits`,
}); });
return body; return body;
@ -306,7 +356,8 @@ export default {
filename, filename,
sha, sha,
}) { }) {
const result = (await request(token, { const refreshedToken = await this.refreshToken(token);
const result = (await request(refreshedToken, {
url: `https://gitee.com/api/v5/gists/${gistId}/${sha}`, url: `https://gitee.com/api/v5/gists/${gistId}/${sha}`,
})).body.files[filename]; })).body.files[filename];
if (!result) { if (!result) {