Last active
February 3, 2024 00:42
-
-
Save thameera/2dfb3dff6ed2ec461aef7a7a2e3d3250 to your computer and use it in GitHub Desktop.
Actions redirect example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Handler that will be called during the execution of a PostLogin flow. | |
* | |
* @param {Event} event - Details about the user and the context in which they are logging in. | |
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. | |
*/ | |
exports.onExecutePostLogin = async (event, api) => { | |
// Craft a signed session token | |
const token = api.redirect.encodeToken({ | |
secret: 'keyboardcat', // IMPORTANT: Read this from event.secrets | |
expiresInSeconds: 60, | |
payload: { | |
// Custom claims to be added to the token | |
email: event.user.email, | |
externalUserId: 1234, | |
}, | |
}); | |
// Send the user to http://localhost:3000/redirect along | |
// with a `session_token` query string param including | |
// the email. | |
api.redirect.sendUserTo("http://localhost:3000/redirect", { | |
query: { session_token: token } | |
}); | |
}; | |
/** | |
* Handler that will be invoked when this action is resuming after an external redirect. If your | |
* onExecutePostLogin function does not perform a redirect, this function can be safely ignored. | |
* | |
* @param {Event} event - Details about the user and the context in which they are logging in. | |
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login. | |
*/ | |
exports.onContinuePostLogin = async (event, api) => { | |
const payload = api.redirect.validateToken({ | |
secret: 'keyboardcat', // IMPORTANT: Read this from event.secrets | |
tokenParameterName: 'my_token', | |
}); | |
console.log(payload); | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* IMPORTANT: | |
* This code is meant for demo purposes only, and is not production-ready. | |
* More info: https://auth0.com/docs/actions/triggers/post-login/redirect-with-actions | |
*/ | |
const express = require('express') | |
const jwt = require('jsonwebtoken') | |
const PORT = process.env.PORT || 3000 | |
const SECRET = 'keyboardcat' // For demo purposes only. Should not be committed in source file. | |
const TENANT_DOMAIN = 'tham.auth0.com' | |
const app = express() | |
/* | |
* Validate the incoming token from Auth0 | |
* This can be generated in the Action by the api.redirect.encodeToken() method | |
*/ | |
const validateIncomingToken = (req) => { | |
if (!req.query || !req.query.session_token) { | |
throw 'No session_token found' | |
} | |
try { | |
const decoded = jwt.verify(req.query.session_token, SECRET) | |
return decoded | |
} catch (e) { | |
throw 'Invalid session_token' | |
} | |
} | |
/* | |
* Generate new session token to be sent to Auth0 | |
*/ | |
const generateNewToken = (data, state) => { | |
const payload = { | |
sub: data.sub, // Mandatory, must match incoming token's sub | |
iss: 'my-redirect-app', // Optional, not validated | |
state, // Mandatory, validated by Auth0 | |
color: 'blue', // Optional custom parameters to be used in Actions | |
} | |
// Even though iat and exp are not added above, they are implicitly added by the jwt library | |
const token = jwt.sign(payload, SECRET, { expiresIn: '60s' }) | |
return token | |
} | |
app.get('/redirect', (req, res) => { | |
try { | |
const incomingData = validateIncomingToken(req) | |
const newToken = generateNewToken(incomingData, req.query.state) | |
const url = `https://${TENANT_DOMAIN}/continue?state=${req.query.state}&my_token=${newToken}` | |
res.redirect(url) | |
} catch (e) { | |
res.send(e) | |
} | |
}) | |
app.listen(PORT, () => { | |
console.log(`App listening at http://localhost:${PORT}`) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The token coming from the Action can/should be consumed immediately and verified. Even if the user stays a long time on the redirected page, you would generally not need to validate that token again. Also note that the token we send back to Auth0 is a new one and different from the one we received from Auth0.
So ideally there shouldn't be a situation where the token fails to validates due to expiry (unless some user is trying to replay a request, in which case it should rightly be denied).