මෑතකදී, දේශීයව ගබඩා කර ඇති JWT භාවිතා කරන විට මගේ තීරණාත්මක අන්ත ලක්ෂ්ය කිහිපයක් වඩාත් ආරක්ෂිත කරන්නේ කෙසේදැයි මම සිතමින් සිටියෙමි.
එය ආරක්ෂාව සඳහා හොඳම පරිචය නොවිය හැකිය (XSS ප්රහාරවල හැකියාව නිසා), නමුත් මෙය මා විසින් සකස් නොකළ අවශ්යතාවයකි. මට අනුවර්තනය වීමට සිදු විය.
එබැවින් මෙය වඩාත් ආරක්ෂිත කිරීම සඳහා, මම විසඳුමක් සොයාගෙන ඇත, එය ඔබටත් උපකාරී වනු ඇතැයි බලාපොරොත්තු වෙමි.
JWT යනු කුමක්දැයි අප සැවොම දන්නා බව මම උපකල්පනය කරමි - පසුපෙළ සේවාව මගින් නිකුත් කරන ලද ටෝකනයක්, එය ඉදිරිපස මඟින් වෙනස් කළ නොහැක, මන්ද එය අත්සන වෙනස් කර ස්වයංක්රීයව ටෝකනය අවලංගු කරයි.
ටෝකනය සොරකම් කළ හැකි තත්වය හමුවන තුරු එය විශිෂ්ටයි - XSS ප්රහාරයේදී මගේ නඩුවේ මෙන්. බොහෝ වෙබ් අඩවි HTTP-පමණි කුකී වෙනුවට දේශීය ගබඩාවේ ටෝකන ගබඩා කරයි, එබැවින් ඒවා ද අවදානමට ලක් වේ.
ඉතින්, එම ටෝකනය ඉදිරිපස ගබඩා කරන ආකාරය වෙනස් කිරීමට නොහැකි වූ විට, අපි ටෝකනය නිකුත් කරන ආකාරය සහ වලංගු කරන ආකාරය වෙනස් කළ යුතු අතර, මට ඔබට සරල විසඳුමක් හඳුන්වා දීමට අවශ්ය මොහොත මෙයයි - JWT with Hashed fingerprint, නමුත් අපි code එක බලමු
අපි උපකල්පනය කරමු, අපට ටෝකන නිකුත් කිරීමට අවසන් ලක්ෂ්යයක් ඇති බව, එය පුරනය වීමේ අන්ත ලක්ෂ්යය ලෙස හඳුන්වමු.
@Controller('v1/sign-in') export class SignInAction { constructor(private jwtService: JwtService) {} @Post() async handle( @Req() request: Request, @Body() body: SignInHttpRequest, ): Promise<SignInHttpResponse> { const ip = request.headers['x-forwarded-for'] || request.socket.remoteAddress; const userAgent = request.headers['user-agent']; const token = this.jwtService.sign({ email: body.email, fingerprint: getSHA512Hash(`${ip}${userAgent}`), // It's worth to mention, that to make it even more secure, you should add salt }); return { token, }; } }
ඉතින් අපි මෙතන කරන්නේ, මූලික වශයෙන්, සම්බන්ධ වන පරිශීලකයාගෙන් පරිශීලක නියෝජිතයා සහ දුරස්ථ IP එකතු කිරීම, එය හෑෂ් කිරීම සහ පසුව එය JWT ටෝකනයට දැමීම, එබැවින් පරිශීලකයා හෝ ප්රහාරකයා JWT ටෝකනය තුළ ඇති දේ බැලීමට කැමති වුවද, ඔවුන් පමණක් කරනු ඇත. සමහර අහඹු හැෂ් අගයක් බලන්න
නමුත් එය මගේ ආරක්ෂාව වැඩි කරන්නේ කෙසේදැයි ඔබ අසයි? අපි බලමු අපේ දෙවන අන්ත ලක්ෂ්යය, ඇඟිලි සලකුණ පෙන්වන්න
@Controller('v1/fingerprint') @UseGuards(AuthGuard(JWT_STRATEGY)) export class ShowFingerPrintAction { @Get() async handle(@Req() request) { return { fingerprint: request.user.fingerprint, }; } }
මුලදී, එය විශේෂ දෙයක් නොවේ. ඉල්ලීමෙන් ඇඟිලි සලකුණ ලබා දෙන අන්ත ලක්ෂ්යය, එසේ නම් එය වඩාත් ආරක්ෂිත කරන්නේ කුමක් ද? JWT_StrateGY!
export const JWT_STRATEGY = 'JWT'; @Injectable() export class JwtStrategy extends PassportStrategy(Strategy, JWT_STRATEGY) { constructor() { super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, secretOrKey: 'hard!to-guess_secret', passReqToCallback: true, }); } async validate(request: Request, payload: any): Promise<any> { const fingerprint = payload.fingerprint; const ip = request.headers['x-forwarded-for'] || request.socket.remoteAddress; const userAgent = request.headers['user-agent']; const calculatedFingerprint = getSHA512Hash(`${ip}${userAgent}`); // It's worth to mention, that to make it even more secure, you should add salt if (fingerprint !== calculatedFingerprint) { throw new BadRequestException('Invalid fingerprint'); } return payload; } }
ඔබට පෙනෙන පරිදි, උපාය මාර්ගයේදී, අපි ඒවා පුරනය වීමේ අන්ත ලක්ෂ්යයෙන් උපුටා ගත් විට සහ ඒවා සංසන්දනය කිරීමේදී සමාන අගයන් උපුටා ගනිමින් - IP හෝ පරිශීලක නියෝජිතයා වෙනස් වී ඇත්නම්, අපි අපගේ ඇඟිලි සලකුණු අන්ත ලක්ෂ්යයට ප්රවේශය ප්රතික්ෂේප කරන්නෙමු.
ප්රහාරකයා අපේ ටෝකනය සොරකම් කළත් ඔහුට එයින් කිසිවක් කළ නොහැක, මන්ද මෙයයි
අපගේ තීරණාත්මක අවසාන ලක්ෂ්යය ඉතා සරල ආකාරයකින් අපට ආරක්ෂා කළ හැක්කේ එලෙසය, නමුත් ඇත්ත වශයෙන්ම, සමහර ගනුදෙනු තිබේ
පළමු ගැටළුව සඳහා, ඔබට ඇත්ත වශයෙන්ම IP සඳහා පමණක් පරීක්ෂා කළ හැකි අතර ටෝකනයක් නිකුත් කිරීමේදී එය හැෂ් නොකරන්න, නමුත් විභව ප්රහාරකයා ප්රහාරයේ දෛශිකය (IP වංචා කිරීම හෝ වෙනත් ක්රම) දනී, එබැවින් සමහරක් කැප කිරීම වඩා ආරක්ෂිත වේ. ආරක්ෂාව සඳහා කාර්ය සාධනය.
ඔබගේ තීරණාත්මක අවසාන ලක්ෂ්යවලට අමතර ආරක්ෂක ස්ථරයක් හඳුන්වා දීමට මෙම ක්රමය ඔබට උපකාර වනු ඇතැයි මම බලාපොරොත්තු වෙමි.
වැඩ කරන මූල කේතය වෙත සබැඳිය: මූලාශ්ර කේතය
ඉඟි: