从 Cognito 收到 JWT Token 后如何存储?通过 Cognito 托管 UI 登录

Posted

技术标签:

【中文标题】从 Cognito 收到 JWT Token 后如何存储?通过 Cognito 托管 UI 登录【英文标题】:How do I store JWT Token after receiving from Cognito? Logging in via the Cognito Hosted UI 【发布时间】:2021-02-04 15:44:42 【问题描述】:

架构:前端 Angular,后端 nodejs/express。

目前的设置工作如下:

    通过 Cognito 托管 UI 登录网站 这会重定向到我们的主页并向我们发送 URL 中的代码 我在 Angular 中下拉了这段代码

import  Component, OnInit  from '@angular/core';
import  DbService  from '../db.service';
import  Iss  from '../db.service';
import  Router, ActivatedRoute  from '@angular/router';
import  Http, Response, RequestOptions, Headers from '@angular/http';



@Component(
  selector: 'app-dashboard'
)
export class GroupSelectionComponent implements OnInit 

  cognitoCode: string;

  constructor(
    private DbService: DbService,
    private route: ActivatedRoute,
    private router: Router
    ) 



  ngOnInit() 

    this.route.queryParams
    .subscribe(params => 
      console.log(params);
      console.log(params.code);
      this.cognitoCode = params.code;
    );  

  this.DbService.getIss(this.cognitoCode).subscribe(
    iss => this.iss = iss
    
    
  );

在代码中,您将看到我将 congitocode 传递给 getIss 的 dbservice。

db.service

getIss(cognitoCode ): Observable<Issuer[]> 
  const url = hosturl +'i_l';
  // let header: HttpHeaders = new HttpHeaders();
  const httpOptions = 
    headers: new HttpHeaders(
      'Access-Control-Allow-Origin':  '*',
      'Content-Type': 'application/json',
      'Authorization': cognitoCode 
    )
  ;
  let params = new HttpParams()
  console.log(httpOptions.headers);
  return this._http.get(url, httpOptions)
  .pipe(
    map((res) => 
      console.log(res);
      return <Issuer[]> res;
    )
  );

然后我将代码作为我的 GET 请求标头的一部分发送到后端。

GET 然后使用这些设置访问我的后端路由器。

var authMiddleware = require('../middleware/AuthMiddleware.js');
router.get('/i_l', authMiddleware.Validate, i_l.get);

然后这将调用我的 authMiddleware,它采用 Cognito 托管 UI 提供的代码,并使用针对 oauth2/token 的 POST 来获取我的 JWT 令牌。

然后解析该令牌,用于与 https://cognito-idp.us-east-2.amazonaws.com/REMOVED/.well-known/jwks.json 进行比较。

一旦验证请求继续,我会从后端取回数据。

    // POST that trades the code for a token with cognito
var options = 
  'method': 'POST',
  'url': 'https://REMOVED.amazoncognito.com/oauth2/token',
  'headers': 
    'Content-Type': 'application/x-www-form-urlencoded'
  ,
  form: 
    'grant_type': 'authorization_code',
    'client_id': 'CLIENTIDREMOVED',
    'code': req.headers['authorization'],
    'redirect_uri': 'http://localhost/group-selection'
  
;


// First request gets the JSON request of the token using the POST above
request(options, function (error, response) 
  if (error) throw new Error(error);
    token = JSON.parse(response.body).access_token;
    //localStorage.setItem('token', token);
    // request pull down status based on validitiy of token
    request(
        url : `https://cognito-idp.us-east-2.amazonaws.com/REMOVED/.well-known/jwks.json`,
        json : true
     , function(error, response, body)
         console.log('token: ' + token);
        if (!error && response.statusCode === 200) 
            pems = ;
            var keys = body['keys'];
            for(var i = 0; i < keys.length; i++) 
                 var key_id = keys[i].kid;
                 var modulus = keys[i].n;
                 var exponent = keys[i].e;
                 var key_type = keys[i].kty;
                 var jwk =  kty: key_type, n: modulus, e: exponent;
                 var pem = jwkToPem(jwk);
                 pems[key_id] = pem;
            
            var decodedJwt = jwt.decode(token, complete: true);
                 if (!decodedJwt) 
                     console.log("Not a valid JWT token");
                     res.status(401);
                     return res.send("Not a valid JWT token");
                
             var kid = decodedJwt.header.kid;
                 var pem = pems[kid];
                 if (!pem) 
                     console.log('Invalid token - decodedJwt.header.kid');
                     res.status(401);
                     return res.send("Invalid token - decodedJwt.header.kid");              
                 
             jwt.verify(token, pem, function(err, payload) 
                     if(err) 
                         console.log("Invalid Token - verify");
                         res.status(401);
                         return res.send("Invalid token  - verify");
                      else 
                          console.log("Valid Token.");
                          return next();
                     
                );
         else 
              console.log("Error! Unable to download JWKs");
              res.status(500);
              return res.send("Error! Unable to download JWKs");
        
    );


);

Quesiton -- 我如何设置,以便我取回的 Token 继续为用户服务?

【问题讨论】:

【参考方案1】:
If I understand your question properly then you are trying to validate all your apis through cognito user right?
Then you just need to do two things.
1) Add in header JWT token once you are getting after login. Just store into your application scope and pass everytime whenever any API is calling.

Auth.signIn(data.username, data.password)
    .then(user => 
     
      let jwkToken = user.getSignInUserSession().getAccessToken().getJwtToken();
      // Store above value in singletone object or application scope.
    )
    .catch(err => 
      //error
    );
    
    
Now When API is calling  pass  jwkToken as header.

2) Then Go AWS ApiGateWay Console and add into Authorizers.
 

【讨论】:

感谢您的回复——这将存在于代码的哪一部分? 你在考虑 Authorizers 吗?请指出。我为我的项目实施并对其进行了定制。因此,您的应用程序肯定存在一些差异。但是,如果您需要代码,那么我必须向您发送图像或过滤代码。

以上是关于从 Cognito 收到 JWT Token 后如何存储?通过 Cognito 托管 UI 登录的主要内容,如果未能解决你的问题,请参考以下文章

如何验证从 Cognito 获得的 jwt 令牌

AWS Cognito 和 Flask 应用程序无法从 url 获取 jwt

token令牌和jwt

为啥我的来自 Amazon Cognito 的 JWT 令牌具有无效签名?

JWT详解

来自客户端 javascript 的错误 400 Cognito /oauth2/token 端点