From bb73b83edf481fd8c298b4255347c509f27cd80c Mon Sep 17 00:00:00 2001 From: N08I40K Date: Sun, 26 Jan 2025 19:20:16 +0400 Subject: [PATCH] Switch VK ID authentication to use JWT tokens - Replace access token with JWT id token - Add JWT public key for VK ID - Implement JWT verification and decoding - Validate JWT issuer and app ID --- src/auth/auth.service.ts | 44 +++++++++++++++++++++++----------------- src/contants.ts | 15 ++++++++++++++ src/vkid/vkid.service.ts | 8 ++++---- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 1f7d26f..3f788fa 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -9,13 +9,14 @@ import { compare, genSalt, hash } from "bcrypt"; import UserRole from "../users/user-role.enum"; import User from "../users/entity/user.entity"; import ChangePasswordDto from "./dto/change-password.dto"; -import axios from "axios"; import SignInErrorDto, { SignInErrorCode } from "./dto/sign-in-error.dto"; import { SignUpDto, SignUpVKDto } from "./dto/sign-up.dto"; import SignUpErrorDto, { SignUpErrorCode } from "./dto/sign-up-error.dto"; import { SignInDto, SignInVKDto } from "./dto/sign-in.dto"; import ObjectID from "bson-objectid"; import UserDto from "../users/dto/user.dto"; +import { decodeJwt, verifyJwtSignature } from "firebase-admin/lib/utils/jwt"; +import { vkIdConstants } from "../contants"; @Injectable() export class AuthService { @@ -123,7 +124,7 @@ export class AuthService { /** * Парсит VK ID пользователя по access token * - * @param accessToken - Access token пользователя VK + * @param idToken - Access token пользователя VK * @returns Promise, который разрешается в VK ID пользователя или null в случае ошибки * * @example @@ -134,26 +135,31 @@ export class AuthService { * console.error('Ошибка при получении VK ID'); * } */ - private static async parseVKID(accessToken: string): Promise { - const form = new FormData(); - form.append("access_token", accessToken); - form.append("v", "5.199"); - - const response = await axios.post( - "https://api.vk.com/method/account.getProfileInfo", - form, - { responseType: "json" }, - ); - - const data: { error?: any; response?: { id: number } } = - response.data as object; - - if (response.status !== 200 || data.error !== undefined) { - console.warn(data); + private static async parseVKID(idToken: string): Promise { + try { + await verifyJwtSignature(idToken, vkIdConstants.jwtPubKey, { + issuer: "VK", + jwtid: "21", + }); + } catch { return null; } - return data.response.id; + const decodedToken = await decodeJwt(idToken); + type TokenData = { + iis: string; + sub: number; + app: number; + exp: number; + iat: number; + jti: number; + }; + + const payload = decodedToken.payload as TokenData; + + if (payload.app !== vkIdConstants.clientId) return null; + + return payload.sub; } /** diff --git a/src/contants.ts b/src/contants.ts index d4b14db..32c4ab8 100644 --- a/src/contants.ts +++ b/src/contants.ts @@ -6,6 +6,21 @@ configDotenv(); export const vkIdConstants = { clientId: +process.env.VKID_CLIENT_ID, redirectUri: process.env.VKID_REDIRECT_URI, + jwtPubKey: + "-----BEGIN PUBLIC KEY-----\n" + + "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvsvJlhFX9Ju/pvCz1frB\n" + + "DgJs592VjdwQuRAmnlJAItyHkoiDIOEocPzgcUBTbDf1plDcTyO2RCkUt0pz0WK6\n" + + "6HNhpJyIfARjaWHeUlv4TpuHXAJJsBKklkU2gf1cjID+40sWWYjtq5dAkXnSJUVA\n" + + "UR+sq0lJ7GmTdJtAr8hzESqGEcSP15PTs7VUdHZ1nkC2XgkuR8KmKAUb388ji1Q4\n" + + "n02rJNOPQgd9r0ac4N2v/yTAFPXumO78N25bpcuWf5vcL9e8THk/U2zt7wf+aAWL\n" + + "748e0pREqNluTBJNZfmhC79Xx6GHtwqHyyduiqfPmejmiujNM/rqnA4e30Tg86Yn\n" + + "cNZ6vLJyF72Eva1wXchukH/aLispbY+EqNPxxn4zzCWaLKHG87gaCxpVv9Tm0jSD\n" + + "2es22NjrUbtb+2pAGnXbyDp2eGUqw0RrTQFZqt/VcmmSCE45FlcZMT28otrwG1ZB\n" + + "kZAb5Js3wLEch3ZfYL8sjhyNRPBmJBrAvzrd8qa3rdUjkC9sKyjGAaHu2MNmFl1Y\n" + + "JFQ3J54tGpkGgJjD7Kz3w0K6OiPDlVCNQN5sqXm24fCw85Pbi8SJiaLTp/CImrs1\n" + + "Z3nHW5q8hljA7OGmqfOP0nZS/5zW9GHPyepsI1rW6CympYLJ15WeNzePxYS5KEX9\n" + + "EncmkSD9b45ge95hJeJZteUCAwEAAQ==\n" + + "-----END PUBLIC KEY-----", }; export const jwtConstants = { diff --git a/src/vkid/vkid.service.ts b/src/vkid/vkid.service.ts index 06cc44d..5f312bc 100644 --- a/src/vkid/vkid.service.ts +++ b/src/vkid/vkid.service.ts @@ -21,16 +21,16 @@ export class VKIDService { `redirect_uri=${vkIdConstants.redirectUri}`, ); - const accessToken: string = (response.data as { access_token: string }) - .access_token; + const idToken: string = (response.data as { id_token: string }) + .id_token; - if (!accessToken) { + if (!idToken) { console.error(response.data); return null; } return new OAuthResponseDto({ - accessToken: accessToken, + accessToken: idToken, }); } }