我在 NestJS 服务器上设置了一个 Firebase 护照策略,该策略运行良好,但我不喜欢它在所有通过它的请求上产生的长时间加载时间。因此,我决定缓存解码的 token ,直到它们过期,这大大减少了有效和未过期 token 的加载时间。
但是,我担心这可能存在安全风险。主要是因为这对我来说似乎是一个简单的补充,之前一定有人考虑过它。我想制作 firebase sdk 的人一定考虑过将其添加为一项功能,但为什么他们没有考虑呢?
作为引用,这是我的护照策略的代码:
@Injectable()
export class FirebaseAuthStrategy extends PassportStrategy(Strategy, 'firebase-auth') {
private defaultApp: any;
constructor(
private configService: ConfigService,
@Inject(CACHE_MANAGER) private cacheManager: Cache
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken()
});
const config = this.configService.get<string>('FIREBASE_CONFIG');
if (!config) {
throw new Error('FIREBASE_CONFIG not available. Please ensure the variable is supplied in the `.env` file.');
}
const firebase_params = JSON.parse(config);
this.defaultApp = firebase.initializeApp({
credential: firebase.credential.cert(firebase_params)
});
}
async validate(token: string) {
const cachedFirebaseUser = await this.cacheManager.get(token);
if (cachedFirebaseUser) return cachedFirebaseUser;
const firebaseUser: any = await this.defaultApp
.auth()
.verifyIdToken(token, true)
.catch((err) => {
console.log(err);
throw new UnauthorizedException(err.Message);
});
if (!firebaseUser) {
throw new UnauthorizedException();
}
/**
* input parameter for `Date` or `moment` constructor is in milliseconds for unix timestamps.
* input * 1000 will instantiate correct Date or moment value.
* See here for reference: https://stackoverflow.com/a/45370395/5472560
*/
const exp = moment(+firebaseUser['exp'] * 1000);
const now = moment.now();
const ttl = exp.diff(now, 'seconds');
await this.cacheManager.set(token, firebaseUser, { ttl });
return firebaseUser;
}
}
最佳答案
只要您在 token 过期后不使用解码后的 token 作为授权信号,缓存解码后的 token 就完全安全。缓存 ID token 是一种有效的方法,可以避免在每次调用时都必须对其进行解码。
关于security - 在后端缓存解码的身份验证 token 是不好的做法还是存在重大安全风险?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69161674/