关于login重构

This commit is contained in:
2025-03-21 20:41:01 +08:00
parent 0179fe73a3
commit 8053a3db64
28 changed files with 889 additions and 596 deletions

View File

@@ -12,12 +12,14 @@ export const createCookie = (token: any, ctx: any) => {
if (!domain) {
return;
}
ctx.res.cookie('token', token.token, {
maxAge: token.expireTime,
domain,
sameSite: 'lax',
httpOnly: true,
});
if (ctx.res.cookie) {
ctx.res.cookie('token', token.token, {
maxAge: 7 * 24 * 60 * 60 * 1000, // 过期时间, 设置7天
domain,
sameSite: 'lax',
httpOnly: true,
});
}
};
const clearCookie = (ctx: any) => {
if (!domain) {
@@ -53,8 +55,11 @@ app
.route({
path: 'user',
key: 'login',
middleware: ['auth-can'],
})
.define(async (ctx) => {
const oldToken = ctx.query.token;
const tokenUser = ctx.state?.tokenUser || {};
const { username, email, password, loginType = 'default' } = ctx.query;
if (!username && !email) {
ctx.throw(400, 'username or email is required');
@@ -69,6 +74,15 @@ app
if (!user) {
ctx.throw(500, 'Login Failed');
}
if (tokenUser.id === user.id) {
// 自己刷新自己的token
const token = await User.oauth.resetToken(oldToken, {
...tokenUser.oauthExpand,
});
createCookie(token, ctx);
ctx.body = token;
return;
}
if (!user.checkPassword(password)) {
ctx.throw(500, 'Password error');
}
@@ -89,11 +103,18 @@ app
})
.addTo(app);
app
.route('user', 'auth')
.route({
path: 'user',
key: 'auth',
middleware: ['auth-can'],
})
.define(async (ctx) => {
const { checkToken: token } = ctx.query;
try {
const result = await User.verifyToken(token);
if (result) {
delete result.oauthExpand;
}
ctx.body = result || {};
} catch (e) {
ctx.throw(401, 'Token InValid ');
@@ -102,7 +123,9 @@ app
.addTo(app);
app
.route('user', 'updateSelf', {
.route({
path: 'user',
key: 'updateSelf',
middleware: ['auth'],
})
.define(async (ctx) => {
@@ -133,6 +156,60 @@ app
ctx.body = await user.getInfo();
})
.addTo(app);
app
.route({
path: 'user',
key: 'switchCheck',
middleware: ['auth'],
})
.define(async (ctx) => {
const token = ctx.query.token;
const { username, accessToken } = ctx.query.data || {};
if (accessToken && username) {
const accessUser = await User.verifyToken(accessToken);
const refreshToken = accessUser.oauthExpand?.refreshToken;
if (refreshToken) {
const result = await User.oauth.refreshToken(refreshToken);
createCookie(result, ctx);
ctx.body = result;
return;
} else if (accessUser) {
await User.oauth.delToken(accessToken);
const result = await User.oauth.generateToken(accessUser, {
...accessUser.oauthExpand,
hasRefreshToken: true,
});
createCookie(result, ctx);
ctx.body = result;
return;
}
} else {
const result = await ctx.call(
{
path: 'user',
key: 'switchOrg',
payload: {
data: {
username,
},
token,
},
},
{
res: ctx.res,
req: ctx.req,
},
);
if (result.code === 200) {
ctx.body = result.body;
} else {
ctx.throw(result.code, result.message);
}
}
})
.addTo(app);
app
.route({
path: 'user',
@@ -141,63 +218,60 @@ app
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const { username, type = 'org', loginType } = ctx.query.data || {};
if (!username && type === 'org') {
ctx.throw('username is required');
const token = ctx.query.token;
const tokenUsername = tokenUser.username;
const userId = tokenUser.userId;
let { username } = ctx.query.data || {};
const user = await User.findByPk(userId);
if (!user) {
ctx.throw('user not found');
}
if (tokenUser.username === username) {
// 自己刷新自己的token
const user = await User.findByPk(tokenUser.id);
if (!user) {
ctx.throw('user not found');
}
if (user.type === 'user') {
const token = await user.createToken(null, loginType);
createCookie(token, ctx);
ctx.body = token;
return;
} else if (user.type === 'org' && tokenUser.uid) {
const token = await user.createToken(tokenUser.uid, loginType);
createCookie(token, ctx);
ctx.body = token;
return;
}
if (!username) {
username = user.username;
}
let me: User;
if (tokenUser.uid) {
me = await User.findByPk(tokenUser.uid);
const orgs = await user.getOrgs();
const orgsList = [tokenUser.username, user.username, , ...orgs];
if (orgsList.includes(username)) {
if (tokenUsername === username) {
const result = await User.oauth.resetToken(token);
createCookie(result, ctx);
await User.oauth.delToken(token);
ctx.body = result;
} else {
const user = await User.findOne({ where: { username } });
const result = await user.createToken(userId, 'default');
createCookie(result, ctx);
ctx.body = result;
}
} else {
me = await User.findByPk(tokenUser.id); // 真实用户
ctx.throw(403, 'Permission denied');
}
})
.addTo(app);
app
.route({
path: 'user',
key: 'refreshToken',
})
.define(async (ctx) => {
const { refreshToken } = ctx.query.data || {};
try {
if (!refreshToken) {
ctx.throw(400, 'Refresh Token is required');
}
const result = await User.oauth.refreshToken(refreshToken);
if (result) {
console.log('refreshToken result', result);
createCookie(result, ctx);
ctx.body = result;
} else {
ctx.throw(500, 'Refresh Token Failed, please login again');
}
} catch (e) {
console.log('refreshToken error', e);
ctx.throw(400, 'Refresh Token Failed');
}
if (!me || me.type === 'org') {
console.log('switch Error ', me.username, me.type);
ctx.throw('Permission denied');
}
if (type === 'user') {
const token = await me.createToken(null, loginType);
createCookie(token, ctx);
ctx.body = token;
return;
}
const orgUser = await User.findOne({ where: { username } });
if (!orgUser) {
ctx.throw('org user not found');
}
if (orgUser.type === 'user') {
// 想转换的type===org, 但实际上这个用户名是一个用户, 比如org调用switchOrg root
const token = await orgUser.createToken(null, loginType);
createCookie(token, ctx);
ctx.body = token;
return;
}
const user = await Org.findOne({ where: { username } });
const users = user.users;
const index = users.findIndex((u) => u.uid === me.id);
if (index === -1) {
ctx.throw('Permission denied');
}
const token = await orgUser.createToken(me.id, loginType);
createCookie(token, ctx);
ctx.body = token;
})
.addTo(app);

View File

@@ -52,6 +52,8 @@ app
await org.addUser(user, { needPermission: true, role: role || 'user', operateId, isAdmin: !!tokenAdmin });
} else if (action === 'remove') {
await org.removeUser(user, { needPermission: true, operateId, isAdmin: !!tokenAdmin });
} else if (action === 'update') {
await org.addUser(user, { needPermission: true, role: role || 'user', operateId, isAdmin: !!tokenAdmin });
} else {
ctx.throw('操作错误');
}

View File

@@ -143,6 +143,7 @@ app
path: 'org',
key: 'hasUser',
middleware: ['auth'],
description: '判断当前username这个组织是否在当前用户的组织中。如果有返回当前组织的用户信息否则返回null',
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
@@ -159,7 +160,13 @@ app
};
return;
}
const usernameUser = await User.findOne({ where: { username } });
const usernameUser = await User.findOne({
where: { username },
attributes: {
exclude: ['password', 'salt'],
},
});
if (!usernameUser) {
ctx.body = {
uid: null,