nestjs-jwt令牌(COGNITO生成)验证失败



我们有一个使用COGNITO用户池的应用程序,可以使用oauth2启用SSO;成功登录后,COGNITO生成令牌并返回;aPI将使用该令牌进行后续调用;我们的API受NESTJS AuthGuards保护;

问题是当我们通过在"API"中传递任何垃圾来测试API时;"授权";类似标题的";承载xyz";它有效,不会出现任何错误。

oauth2代码,其中它与COGNITO进行对话以生成令牌;

enter code here
export class OAuth2Strategy extends PassportStrategy(Strategy, 'oauth2') { 
constructor() {
const serverURL = config.get('authDetails.SERVER_URL');
let appRootURL:any = process.env.NODE_ENV === 'localhost' ? 'http://localhost:' + config.get('app.port') : config.get('app.rootUrl');
if (!appRootURL.endsWith('/')) {
appRootURL += '/';
}  
const appBaseURL = `${appRootURL}${config.get('globalPrefix')}`;
const loginCallbackURL = `${appBaseURL}/auth/login/callback`;
super({
authorizationURL: `${serverURL}oauth2/authorize`,
tokenURL: `${serverURL}oauth2/token`,
clientID: config.get('CLIENT_ID'),
//clientSecret: config.get('CLIENT_SECRET'),
callbackURL: loginCallbackURL,
scope: ['openid', 'profile'],
state: (100000000000).toString(36)
}, function(accessToken: string, refreshToken: string, params: any, profile: any, done: VerifyCallback) {
done(null, {
accessToken: accessToken
});
});
}

NEST JS承载策略代码

export class BearerStrategy extends PassportStrategy(Strategy, 'bearer') {
async validate(accessToken: string, done: VerifyCallback) {

const user = {
accessToken
}
done(null, user);
}

}

export class BearerStrategy extends PassportStrategy(Strategy, 'bearer') {
async validate(accessToken: string, done: VerifyCallback) {

const user = {
accessToken
}
done(null, user);
}

}

JWT战略类

export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
console.log(config.get('CLIENT_SECRET'))
console.log(JSON.stringify(ExtractJwt.fromAuthHeaderAsBearerToken()))
super({
secretOrKey:  
passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-XXXX/.well-known/jwks.json',

}), 

jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
//jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('JWT'),
// ignoreExpiration: false,  
// secretOrKey: config.get('CLIENT_SECRET'),
algorithms:["RS256"],
issuer : "https://cognito-idp.us-east-1.amazonaws.com/us-east-XXXX",
audience: "client_id1234"

});
}
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor() {
console.log(config.get('CLIENT_SECRET'))
console.log(JSON.stringify(ExtractJwt.fromAuthHeaderAsBearerToken()))
super({
secretOrKey:  
passportJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-XXXX/.well-known/jwks.json',

}), 

jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
//jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('JWT'),
// ignoreExpiration: false,  
// secretOrKey: config.get('CLIENT_SECRET'),
algorithms:["RS256"],
issuer : "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_XXXX",
audience: "client_id12344"

});
}

现在我们使用身份验证保护来保护它们

@ApiTags("Root")
@Get("/lookup")
@UseGuards(AuthGuard("bearer"))
async get() {
return "got the data.."
}
@ApiTags("Root")
@Get("/test")
@UseGuards(AuthGuard("jwt"))
async getSample() {
return "got the data.."
}

不确定为什么Passport验证不起作用从Bearer和JWT策略调用的验证方法。而Bearer没有给出JWT抛出的错误";cb:不是函数";我不太理解,在网络方面也没有太多帮助。

这个JwtStrategy应该可以工作。请将aws-regioncognito-user-pool-id替换为您的。

import { ExtractJwt, Strategy } from 'passport-jwt';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { map } from 'rxjs/operators';
import find from 'lodash/find';
import jwkToPem from 'jwk-to-pem';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly httpService: HttpService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKeyProvider: (_, token, done) => {
const jwksUri =
'https://cognito-idp.<aws-region>.amazonaws.com/<cognito-user-pool-id>/.well-known/jwks.json';
this.httpService
.get(jwksUri)
.pipe(
map((response) => {
const {
data: { keys },
} = response;
const tokenSections = (token || '').split('.');
if (tokenSections.length < 2) {
throw Error('something went wrong');
}
const headerJSON = Buffer.from(
tokenSections[0],
'base64',
).toString('utf8');
const header = JSON.parse(headerJSON);
const jwk = find(keys, (key) => key.kid === header.kid);
if (!jwk) {
throw Error('something went wrong');
}
return jwkToPem(jwk);
}),
)
.subscribe({
next(pem) {
done(null, pem);
},
error(err) {
done(err.message, null);
},
});
},
});
}
async validate(payload: any) {
return { userId: payload.sub, username: payload.username };
}
}

最新更新