hoppscotch修改为任意oauth单点登录,理论无视更新
- 内容介绍
- 文章标签
- 相关推荐
昨天研究了一天 hoppscotch,邮箱登录太吐槽了,github登录,服务器在内网,无法连接github,上代理又太卡了,然后想到替换github单点地址
直接映射 github 单点js文件,覆盖地址
以 linuxdo 单点登录为例
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubStrategy = void 0;
const passport_github2_1 = require("passport-github2");
const passport_1 = require("@nestjs/passport");
const common_1 = require("@nestjs/common");
const auth_service_1 = require("../auth.service");
const user_service_1 = require("../../user/user.service");
const O = __importStar(require("fp-ts/Option"));
const E = __importStar(require("fp-ts/Either"));
const config_1 = require("@nestjs/config");
const utils_1 = require("../../utils");
const errors_1 = require("../../errors");
let GithubStrategy = class GithubStrategy extends (0, passport_1.PassportStrategy)(passport_github2_1.Strategy) {
authService;
usersService;
configService;
constructor(authService, usersService, configService) {
super({
clientID: configService.get('INFRA.GITHUB_CLIENT_ID'),
clientSecret: configService.get('INFRA.GITHUB_CLIENT_SECRET'),
callbackURL: configService.get('INFRA.GITHUB_CALLBACK_URL'),
scope: [configService.get('INFRA.GITHUB_SCOPE')],
store: true,
authorizationURL: 'https://connect.linux.do/oauth2/authorize',
tokenURL: 'https://connect.linux.do/oauth2/token',
userProfileURL: 'https://connect.linux.do/api/user',
});
this.authService = authService;
this.usersService = usersService;
this.configService = configService;
}
async validate(accessToken, refreshToken, profile, done) {
console.log("profile", profile)
// ***注意这里的数据兼容,自行替换
//profile.username = profile._json.username
//profile.profileUrl = profile._json.picture
//profile.id = profile._json.username
const email = profile.emails?.[0].value;
if (!(0, utils_1.validateEmail)(email))
throw new common_1.UnauthorizedException(errors_1.AUTH_EMAIL_NOT_PROVIDED_BY_OAUTH);
const user = await this.usersService.findUserByEmail(email);
if (O.isNone(user)) {
const createdUser = await this.usersService.createUserSSO(accessToken, refreshToken, profile);
return createdUser;
}
if (!user.value.displayName || !user.value.photoURL) {
const updatedUser = await this.usersService.updateUserDetails(user.value, profile);
if (E.isLeft(updatedUser)) {
throw new common_1.UnauthorizedException(updatedUser.left);
}
}
const providerAccountExists = await this.authService.checkIfProviderAccountExists(user.value, profile);
if (O.isNone(providerAccountExists))
await this.usersService.createProviderAccount(user.value, accessToken, refreshToken, profile);
return user.value;
}
};
exports.GithubStrategy = GithubStrategy;
exports.GithubStrategy = GithubStrategy = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [auth_service_1.AuthService,
user_service_1.UserService,
config_1.ConfigService])
], GithubStrategy);
如果需要使用自定义的oauth地址,请修改上面的地址,还有注意修改用户信息返回的数据,已经加了打印,自行替换相关数据
blowsnow:
authorizationURL: 'https://connect.linux.do/oauth2/authorize', tokenURL: 'https://connect.linux.do/oauth2/token', userProfileURL: 'https://connect.linux.do/api/user',
docker映射文件
version: '3.8'
services:
hoppscotch:
image: hoppscotch/hoppscotch:2026.2.1
ports:
- "127.0.0.1:28881:80"
restart: unless-stopped
command:
- sh
- -c
- |
pnpm exec prisma migrate deploy && node /usr/src/app/aio_run.mjs
volumes:
- ./patch/github.strategy.js:/dist/backend/dist/src/auth/strategies/github.strategy.js
网友解答:
--【壹】--:
昨天研究了一天 hoppscotch,邮箱登录太吐槽了,github登录,服务器在内网,无法连接github,上代理又太卡了,然后想到替换github单点地址
直接映射 github 单点js文件,覆盖地址
以 linuxdo 单点登录为例
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubStrategy = void 0;
const passport_github2_1 = require("passport-github2");
const passport_1 = require("@nestjs/passport");
const common_1 = require("@nestjs/common");
const auth_service_1 = require("../auth.service");
const user_service_1 = require("../../user/user.service");
const O = __importStar(require("fp-ts/Option"));
const E = __importStar(require("fp-ts/Either"));
const config_1 = require("@nestjs/config");
const utils_1 = require("../../utils");
const errors_1 = require("../../errors");
let GithubStrategy = class GithubStrategy extends (0, passport_1.PassportStrategy)(passport_github2_1.Strategy) {
authService;
usersService;
configService;
constructor(authService, usersService, configService) {
super({
clientID: configService.get('INFRA.GITHUB_CLIENT_ID'),
clientSecret: configService.get('INFRA.GITHUB_CLIENT_SECRET'),
callbackURL: configService.get('INFRA.GITHUB_CALLBACK_URL'),
scope: [configService.get('INFRA.GITHUB_SCOPE')],
store: true,
authorizationURL: 'https://connect.linux.do/oauth2/authorize',
tokenURL: 'https://connect.linux.do/oauth2/token',
userProfileURL: 'https://connect.linux.do/api/user',
});
this.authService = authService;
this.usersService = usersService;
this.configService = configService;
}
async validate(accessToken, refreshToken, profile, done) {
console.log("profile", profile)
// ***注意这里的数据兼容,自行替换
//profile.username = profile._json.username
//profile.profileUrl = profile._json.picture
//profile.id = profile._json.username
const email = profile.emails?.[0].value;
if (!(0, utils_1.validateEmail)(email))
throw new common_1.UnauthorizedException(errors_1.AUTH_EMAIL_NOT_PROVIDED_BY_OAUTH);
const user = await this.usersService.findUserByEmail(email);
if (O.isNone(user)) {
const createdUser = await this.usersService.createUserSSO(accessToken, refreshToken, profile);
return createdUser;
}
if (!user.value.displayName || !user.value.photoURL) {
const updatedUser = await this.usersService.updateUserDetails(user.value, profile);
if (E.isLeft(updatedUser)) {
throw new common_1.UnauthorizedException(updatedUser.left);
}
}
const providerAccountExists = await this.authService.checkIfProviderAccountExists(user.value, profile);
if (O.isNone(providerAccountExists))
await this.usersService.createProviderAccount(user.value, accessToken, refreshToken, profile);
return user.value;
}
};
exports.GithubStrategy = GithubStrategy;
exports.GithubStrategy = GithubStrategy = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [auth_service_1.AuthService,
user_service_1.UserService,
config_1.ConfigService])
], GithubStrategy);
如果需要使用自定义的oauth地址,请修改上面的地址,还有注意修改用户信息返回的数据,已经加了打印,自行替换相关数据
blowsnow:
authorizationURL: 'https://connect.linux.do/oauth2/authorize', tokenURL: 'https://connect.linux.do/oauth2/token', userProfileURL: 'https://connect.linux.do/api/user',
docker映射文件
version: '3.8'
services:
hoppscotch:
image: hoppscotch/hoppscotch:2026.2.1
ports:
- "127.0.0.1:28881:80"
restart: unless-stopped
command:
- sh
- -c
- |
pnpm exec prisma migrate deploy && node /usr/src/app/aio_run.mjs
volumes:
- ./patch/github.strategy.js:/dist/backend/dist/src/auth/strategies/github.strategy.js
昨天研究了一天 hoppscotch,邮箱登录太吐槽了,github登录,服务器在内网,无法连接github,上代理又太卡了,然后想到替换github单点地址
直接映射 github 单点js文件,覆盖地址
以 linuxdo 单点登录为例
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubStrategy = void 0;
const passport_github2_1 = require("passport-github2");
const passport_1 = require("@nestjs/passport");
const common_1 = require("@nestjs/common");
const auth_service_1 = require("../auth.service");
const user_service_1 = require("../../user/user.service");
const O = __importStar(require("fp-ts/Option"));
const E = __importStar(require("fp-ts/Either"));
const config_1 = require("@nestjs/config");
const utils_1 = require("../../utils");
const errors_1 = require("../../errors");
let GithubStrategy = class GithubStrategy extends (0, passport_1.PassportStrategy)(passport_github2_1.Strategy) {
authService;
usersService;
configService;
constructor(authService, usersService, configService) {
super({
clientID: configService.get('INFRA.GITHUB_CLIENT_ID'),
clientSecret: configService.get('INFRA.GITHUB_CLIENT_SECRET'),
callbackURL: configService.get('INFRA.GITHUB_CALLBACK_URL'),
scope: [configService.get('INFRA.GITHUB_SCOPE')],
store: true,
authorizationURL: 'https://connect.linux.do/oauth2/authorize',
tokenURL: 'https://connect.linux.do/oauth2/token',
userProfileURL: 'https://connect.linux.do/api/user',
});
this.authService = authService;
this.usersService = usersService;
this.configService = configService;
}
async validate(accessToken, refreshToken, profile, done) {
console.log("profile", profile)
// ***注意这里的数据兼容,自行替换
//profile.username = profile._json.username
//profile.profileUrl = profile._json.picture
//profile.id = profile._json.username
const email = profile.emails?.[0].value;
if (!(0, utils_1.validateEmail)(email))
throw new common_1.UnauthorizedException(errors_1.AUTH_EMAIL_NOT_PROVIDED_BY_OAUTH);
const user = await this.usersService.findUserByEmail(email);
if (O.isNone(user)) {
const createdUser = await this.usersService.createUserSSO(accessToken, refreshToken, profile);
return createdUser;
}
if (!user.value.displayName || !user.value.photoURL) {
const updatedUser = await this.usersService.updateUserDetails(user.value, profile);
if (E.isLeft(updatedUser)) {
throw new common_1.UnauthorizedException(updatedUser.left);
}
}
const providerAccountExists = await this.authService.checkIfProviderAccountExists(user.value, profile);
if (O.isNone(providerAccountExists))
await this.usersService.createProviderAccount(user.value, accessToken, refreshToken, profile);
return user.value;
}
};
exports.GithubStrategy = GithubStrategy;
exports.GithubStrategy = GithubStrategy = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [auth_service_1.AuthService,
user_service_1.UserService,
config_1.ConfigService])
], GithubStrategy);
如果需要使用自定义的oauth地址,请修改上面的地址,还有注意修改用户信息返回的数据,已经加了打印,自行替换相关数据
blowsnow:
authorizationURL: 'https://connect.linux.do/oauth2/authorize', tokenURL: 'https://connect.linux.do/oauth2/token', userProfileURL: 'https://connect.linux.do/api/user',
docker映射文件
version: '3.8'
services:
hoppscotch:
image: hoppscotch/hoppscotch:2026.2.1
ports:
- "127.0.0.1:28881:80"
restart: unless-stopped
command:
- sh
- -c
- |
pnpm exec prisma migrate deploy && node /usr/src/app/aio_run.mjs
volumes:
- ./patch/github.strategy.js:/dist/backend/dist/src/auth/strategies/github.strategy.js
网友解答:
--【壹】--:
昨天研究了一天 hoppscotch,邮箱登录太吐槽了,github登录,服务器在内网,无法连接github,上代理又太卡了,然后想到替换github单点地址
直接映射 github 单点js文件,覆盖地址
以 linuxdo 单点登录为例
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GithubStrategy = void 0;
const passport_github2_1 = require("passport-github2");
const passport_1 = require("@nestjs/passport");
const common_1 = require("@nestjs/common");
const auth_service_1 = require("../auth.service");
const user_service_1 = require("../../user/user.service");
const O = __importStar(require("fp-ts/Option"));
const E = __importStar(require("fp-ts/Either"));
const config_1 = require("@nestjs/config");
const utils_1 = require("../../utils");
const errors_1 = require("../../errors");
let GithubStrategy = class GithubStrategy extends (0, passport_1.PassportStrategy)(passport_github2_1.Strategy) {
authService;
usersService;
configService;
constructor(authService, usersService, configService) {
super({
clientID: configService.get('INFRA.GITHUB_CLIENT_ID'),
clientSecret: configService.get('INFRA.GITHUB_CLIENT_SECRET'),
callbackURL: configService.get('INFRA.GITHUB_CALLBACK_URL'),
scope: [configService.get('INFRA.GITHUB_SCOPE')],
store: true,
authorizationURL: 'https://connect.linux.do/oauth2/authorize',
tokenURL: 'https://connect.linux.do/oauth2/token',
userProfileURL: 'https://connect.linux.do/api/user',
});
this.authService = authService;
this.usersService = usersService;
this.configService = configService;
}
async validate(accessToken, refreshToken, profile, done) {
console.log("profile", profile)
// ***注意这里的数据兼容,自行替换
//profile.username = profile._json.username
//profile.profileUrl = profile._json.picture
//profile.id = profile._json.username
const email = profile.emails?.[0].value;
if (!(0, utils_1.validateEmail)(email))
throw new common_1.UnauthorizedException(errors_1.AUTH_EMAIL_NOT_PROVIDED_BY_OAUTH);
const user = await this.usersService.findUserByEmail(email);
if (O.isNone(user)) {
const createdUser = await this.usersService.createUserSSO(accessToken, refreshToken, profile);
return createdUser;
}
if (!user.value.displayName || !user.value.photoURL) {
const updatedUser = await this.usersService.updateUserDetails(user.value, profile);
if (E.isLeft(updatedUser)) {
throw new common_1.UnauthorizedException(updatedUser.left);
}
}
const providerAccountExists = await this.authService.checkIfProviderAccountExists(user.value, profile);
if (O.isNone(providerAccountExists))
await this.usersService.createProviderAccount(user.value, accessToken, refreshToken, profile);
return user.value;
}
};
exports.GithubStrategy = GithubStrategy;
exports.GithubStrategy = GithubStrategy = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [auth_service_1.AuthService,
user_service_1.UserService,
config_1.ConfigService])
], GithubStrategy);
如果需要使用自定义的oauth地址,请修改上面的地址,还有注意修改用户信息返回的数据,已经加了打印,自行替换相关数据
blowsnow:
authorizationURL: 'https://connect.linux.do/oauth2/authorize', tokenURL: 'https://connect.linux.do/oauth2/token', userProfileURL: 'https://connect.linux.do/api/user',
docker映射文件
version: '3.8'
services:
hoppscotch:
image: hoppscotch/hoppscotch:2026.2.1
ports:
- "127.0.0.1:28881:80"
restart: unless-stopped
command:
- sh
- -c
- |
pnpm exec prisma migrate deploy && node /usr/src/app/aio_run.mjs
volumes:
- ./patch/github.strategy.js:/dist/backend/dist/src/auth/strategies/github.strategy.js

