2016-05-25 19 views
15

Sto utilizzando il pool di utenti Cognito per autenticare gli utenti nel mio sistema. Un'autenticazione corretta fornisce un token ID (JWT), un token di accesso (JWT) e un token di aggiornamento. La documentazione qui, http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html, indica chiaramente che il token di aggiornamento può essere utilizzato per aggiornare il token di accesso, ma non menziona come. La mia domanda è una volta che il mio token di accesso scade, come faccio a utilizzare il token di aggiornamento memorizzato per aggiornare nuovamente il mio token di accesso?Cognito User Pool: come aggiornare il token di accesso utilizzando il token di aggiornamento

Ho cercato attraverso il sdk javascript e non ho trovato alcun metodo per fare lo stesso. Ho sicuramente perso qualcosa.

Inoltre stavo pensando a questo tramite una funzione Lambda che accetta il token di accesso e aggiorna il token e risponde con un token di accesso aggiornato. Sarebbe bello se qualcuno potesse far luce su questo.

Grazie

+1

Come aggiornare il token per un ios-SDK di AWS? –

risposta

11

SDK JavaScript gestisce rinfrescante dei token internamente. Quando chiami "getSession" per ottenere token, in assenza di accessi cache e id validi validi, l'SDK utilizza il token di aggiornamento per ottenere nuovi token di accesso e ID. Invoca l'autenticazione dell'utente, richiedendo all'utente di fornire nome utente e password, solo quando anche il token di aggiornamento è scaduto.

saluti, Mahesh

+2

Mahesh, puoi darci l'esempio di codice lì? – Deep

+0

hi Mahesh (e altri che potrebbero aver bisogno di questo) vedere il link qui https://github.com/aws/amazon-cognito-identity-js in particolare il caso d'uso 16. La sessione restituita contiene i token. –

15

Se ti trovi in ​​una situazione in cui il Cognito Javascript SDK non è andare a lavorare per i vostri scopi, si può ancora vedere come gestisce il processo di aggiornamento nella SDK source:

È possibile vedere in refreshSession che l'endpoint Cognito InitiateAuth viene chiamato con REFRESH_TOKEN_AUTH impostato per il valore AuthFlow e un oggetto inoltrato come valore AuthParameters.

Tale oggetto dovrà essere configurato per soddisfare le esigenze del pool di utenti. In particolare, potrebbe essere necessario passare il numero SECRET_HASH se l'ID client dell'app target ha un segreto client associato all'app. Le app client pool di utenti create per l'uso con l'SDK Javascript al momento non possono contenere un segreto client e pertanto non è necessario un SECRET_HASH per connettersi con loro.

Un'altra avvertenza che potrebbe generare un loop è se il pool utente è impostato per ricordare i dispositivi e non si passa allo DEVICE_KEY insieme al numero REFRESH_TOKEN. L'API Cognito restituisce attualmente un errore "Invalid Refresh Token" se si passa il RefreshToken senza passare anche il numero DeviceKey. Questo errore viene restituito anche se si sta passando un valido RefreshToken. Il thread collegato sopra illumina che, sebbene spero che AWS aggiorni la loro gestione degli errori per essere meno criptico in futuro.

Come discusso in quella discussione, se si utilizza AdminInitiateAuth con ADMIN_NO_SRP_AUTH, il vostro successo payload risposta di autenticazione al momento non contiene NewDeviceMetadata; il che significa che non dovrai far passare nessuno DeviceKey mentre tenti di aggiornare i tuoi token.

mia app richiede un'implementazione in Python, ecco un esempio che ha funzionato per me:

def refresh_token(self, username, refresh_token): 
    try: 
     return client.initiate_auth(
      ClientId=self.client_id, 
      AuthFlow='REFRESH_TOKEN_AUTH', 
      AuthParameters={ 
       'REFRESH_TOKEN': refresh_token, 
       'SECRET_HASH': self.get_secret_hash(username) 
       // Note that SECRET_HASH is missing from JSDK 
       // Note also that DEVICE_KEY is missing from my example 
      } 
     ) 
    except botocore.exceptions.ClientError as e: 
     return e.response 
+3

Grazie mille @afilbert per il post informativo. Non stavo passando in DEVICE_KEY e ricevevo l'errore "Token di aggiornamento non valido", che è una pessima gestione degli errori sul lato AWS. –

+1

Bella risposta, @ afilbert - upvoted. (Sfortunatamente gli utenti SO hanno iniziato a trattare gli upvotes come soldi per le spese personali qualche anno fa.) – SexxLuthor

+1

Grazie mille per il puntatore sul tasto del dispositivo! (Ho disabilitato il tracciamento dei dispositivi e funziona di nuovo bene). – Dynite

2

ho lottato con questo pure in Javascript. Ecco la mia soluzione, si basa su https://github.com/aws/amazon-cognito-identity-js, ma non si basa sulla memorizzazione in modo da poterlo utilizzare in una funzione lambda se lo si desidera. Modifica: Codice fisso, grazie a pastelli

const userPool = new AWSCognito.CognitoUserPool({ 
    UserPoolId: <COGNITO_USER_POOL>, 
    ClientId: <COGNITO_APP_ID> 
}) 

userPool.client.makeUnauthenticatedRequest('initiateAuth', { 
    ClientId: <COGNITO_APP_ID>, 
    AuthFlow: 'REFRESH_TOKEN_AUTH', 
    AuthParameters: { 
    'REFRESH_TOKEN': <REFRESH_TOKEN> // client refresh JWT 
    } 
}, (err, authResult) => { 
    if (err) { 
    throw err 
    } 
    console.log(authResult) // contains new session 
}) 
+0

Funziona, tuttavia, il formato ** AuthParameters ** deve essere "REFRESH_TOKEN": '. Tieni inoltre presente che se hai attivato il monitoraggio dei dispositivi, devi passare la chiave del dispositivo dei clienti in ** AuthParameters ** o disattivare il rilevamento del dispositivo. – Crayons

0

rinfrescante una sessione con il amazon-cognito-identità-js del browser SDK; lo fa principalmente per te e, a meno che tu non stia facendo qualcosa di insolito, non dovrai gestire direttamente il token di aggiornamento. Ecco cosa è necessario sapere:

Supponete di avere istanziato la piscina utente in questo modo:

const userPool = new AmazonCognitoIdentity.CognitoUserPool({ 
    UserPoolId: USER_POOL_ID, 
    ClientId: USER_POOL_CLIENT_ID 
}); 

per trovare l'ultimo nome utente autenticato, si dovrebbe fare questo:

const cognitoUser = cognitoUserPool.getCurrentUser(); 

Se trova uno, cognitoUser sarà non nullo, e potrai farlo, che aggiornerà i tuoi token dietro le quinte se necessario:

cognitoUser.getSession(function(err, data) { 
    if (err) { 
    // Prompt the user to reauthenticate by hand... 
    } else { 
    const cognitoUserSession = data; 
    const yourIdToken = cognitoUserSession.getIdToken().jwtToken; 
    const yourAccessToken = cognitoUserSession.getAccessToken().jwtToken; 
    } 
}); 

Se non si desidera che questi gettoni persistito nella memoria locale, è possibile:

cognitoUser.signOut(); 

Il modo in cui funziona è, dopo un successo di autenticazione, il browser memorizza i token JWT, compresa quella token di aggiornamento. Memorizza questi nella memoria locale nel tuo browser per impostazione predefinita, sebbene tu possa fornire il tuo oggetto di archiviazione, se lo desideri. Per impostazione predefinita, il token di aggiornamento è valido per 30 giorni, ma è una proprietà (RefreshTokenValidity) di UserPoolClient, che è possibile modificare. Quando fai quanto sopra, getSession() vedrà prima se i token che hai in memoria esistono e sono ancora validi; in caso contrario, proverà ad utilizzare qualsiasi refreshToken che trova lì per autenticarti in una nuova sessione.

La documentazione http://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html indica che gli SDK iOS e Android lo faranno per voi, sebbene non li abbia usati, quindi non posso garantire per questo.

0

Ecco un esempio di come farlo con JavaScript sul lato server utilizzando Node.js.

const AccessToken = new CognitoAccessToken({ AccessToken: tokens.accessToken }); 
const IdToken = new CognitoIdToken({ IdToken: tokens.idToken }); 
const RefreshToken = new CognitoRefreshToken({ RefreshToken: tokens.refreshToken }); 

const sessionData = { 
    IdToken: IdToken, 
    AccessToken: AccessToken, 
    RefreshToken: RefreshToken 
}; 
const userSession = new CognitoUserSession(sessionData); 

const userData = { 
    Username: email, 
    Pool: this.userPool 
}; 

const cognitoUser = new CognitoUser(userData); 
cognitoUser.setSignInUserSession(userSession); 

cognitoUser.getSession(function (err, session) { // You must run this to verify that session (internally) 
    if (session.isValid()) { 
    // Update attributes or whatever else you want to do 
    } else { 
    // TODO: What to do if session is invalid? 
    } 
}); 

Si può vedere un esempio di lavoro completo nel mio post sul blog How to authenticate users with Tokens using Cognito.

Problemi correlati