feat(api-auth): add oauth strategies for github qq wechat

This commit is contained in:
2026-04-04 21:15:32 +08:00
parent 074942fab4
commit 485fe43140
8 changed files with 294 additions and 2 deletions
+56 -1
View File
@@ -1,4 +1,5 @@
import { Body, Controller, Post } from "@nestjs/common";
import { Body, Controller, Get, Post, Req, UseGuards } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { AuthService } from "./auth.service";
import { EmailLoginDto } from "./dto/email-login.dto";
import { RefreshTokenDto } from "./dto/refresh-token.dto";
@@ -43,4 +44,58 @@ export class AuthController {
async revokeRefreshToken(@Body() body: RefreshTokenDto): Promise<{ success: boolean }> {
return this.authService.revokeRefreshToken(body.refreshToken);
}
@Get("oauth/github")
@UseGuards(AuthGuard("github"))
githubLogin(): void {}
@Get("oauth/github/callback")
@UseGuards(AuthGuard("github"))
githubCallback(@Req() req: { user: unknown }): {
success: boolean;
provider: "github";
profile: unknown;
} {
return {
success: true,
provider: "github",
profile: req.user
};
}
@Get("oauth/qq")
@UseGuards(AuthGuard("qq"))
qqLogin(): void {}
@Get("oauth/qq/callback")
@UseGuards(AuthGuard("qq"))
qqCallback(@Req() req: { user: unknown }): {
success: boolean;
provider: "qq";
profile: unknown;
} {
return {
success: true,
provider: "qq",
profile: req.user
};
}
@Get("oauth/wechat")
@UseGuards(AuthGuard("wechat"))
wechatLogin(): void {}
@Get("oauth/wechat/callback")
@UseGuards(AuthGuard("wechat"))
wechatCallback(@Req() req: { user: unknown }): {
success: boolean;
provider: "wechat";
profile: unknown;
} {
return {
success: true,
provider: "wechat",
profile: req.user
};
}
}
+6 -1
View File
@@ -1,12 +1,17 @@
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { JwtModule } from "@nestjs/jwt";
import { PassportModule } from "@nestjs/passport";
import { AuthController } from "./auth.controller";
import { AuthService } from "./auth.service";
import { GithubStrategy } from "./strategies/github.strategy";
import { QqStrategy } from "./strategies/qq.strategy";
import { WechatStrategy } from "./strategies/wechat.strategy";
@Module({
imports: [
ConfigModule,
PassportModule.register({ session: false }),
JwtModule.registerAsync({
inject: [ConfigService],
useFactory: (configService: ConfigService) => {
@@ -22,6 +27,6 @@ import { AuthService } from "./auth.service";
})
],
controllers: [AuthController],
providers: [AuthService]
providers: [AuthService, GithubStrategy, QqStrategy, WechatStrategy]
})
export class AuthModule {}
@@ -0,0 +1,32 @@
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { PassportStrategy } from "@nestjs/passport";
import { Profile, Strategy } from "passport-github2";
@Injectable()
export class GithubStrategy extends PassportStrategy(Strategy, "github") {
constructor(configService: ConfigService) {
super({
clientID: configService.get<string>("OAUTH_GITHUB_CLIENT_ID") ?? "github-client-id",
clientSecret:
configService.get<string>("OAUTH_GITHUB_CLIENT_SECRET") ?? "github-client-secret",
callbackURL:
configService.get<string>("OAUTH_GITHUB_CALLBACK_URL") ??
"http://localhost:3000/auth/oauth/github/callback",
scope: ["user:email"]
});
}
async validate(
accessToken: string,
refreshToken: string,
profile: Profile
): Promise<{ provider: "github"; accessToken: string; refreshToken: string; profile: Profile }> {
return {
provider: "github",
accessToken,
refreshToken,
profile
};
}
}
@@ -0,0 +1,33 @@
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy } from "passport-oauth2";
@Injectable()
export class QqStrategy extends PassportStrategy(Strategy, "qq") {
constructor(configService: ConfigService) {
super({
authorizationURL:
configService.get<string>("OAUTH_QQ_AUTH_URL") ?? "https://graph.qq.com/oauth2.0/authorize",
tokenURL:
configService.get<string>("OAUTH_QQ_TOKEN_URL") ?? "https://graph.qq.com/oauth2.0/token",
clientID: configService.get<string>("OAUTH_QQ_CLIENT_ID") ?? "qq-client-id",
clientSecret: configService.get<string>("OAUTH_QQ_CLIENT_SECRET") ?? "qq-client-secret",
callbackURL:
configService.get<string>("OAUTH_QQ_CALLBACK_URL") ??
"http://localhost:3000/auth/oauth/qq/callback",
scope: ["get_user_info"]
});
}
async validate(
accessToken: string,
refreshToken: string
): Promise<{ provider: "qq"; accessToken: string; refreshToken: string }> {
return {
provider: "qq",
accessToken,
refreshToken
};
}
}
@@ -0,0 +1,36 @@
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy } from "passport-oauth2";
@Injectable()
export class WechatStrategy extends PassportStrategy(Strategy, "wechat") {
constructor(configService: ConfigService) {
super({
authorizationURL:
configService.get<string>("OAUTH_WECHAT_AUTH_URL") ??
"https://open.weixin.qq.com/connect/qrconnect",
tokenURL:
configService.get<string>("OAUTH_WECHAT_TOKEN_URL") ??
"https://api.weixin.qq.com/sns/oauth2/access_token",
clientID: configService.get<string>("OAUTH_WECHAT_CLIENT_ID") ?? "wechat-client-id",
clientSecret:
configService.get<string>("OAUTH_WECHAT_CLIENT_SECRET") ?? "wechat-client-secret",
callbackURL:
configService.get<string>("OAUTH_WECHAT_CALLBACK_URL") ??
"http://localhost:3000/auth/oauth/wechat/callback",
scope: ["snsapi_login"]
});
}
async validate(
accessToken: string,
refreshToken: string
): Promise<{ provider: "wechat"; accessToken: string; refreshToken: string }> {
return {
provider: "wechat",
accessToken,
refreshToken
};
}
}