Nextjs-auth0: Redirect after login

Created on 2 Nov 2019  路  6Comments  路  Source: auth0/nextjs-auth0

Redirect users after login

As described in https://auth0.com/docs/users/guides/redirect-users-after-login

Is it possible to redirect a user to a defined page after login, and if so, how would you do it with this library?
My use case is I have a user who tried to access a specific page which required authentication, and I want to redirect back to that page after login.

On the client-side I would have local stored a nonce, and retrieved it on the callback. What is the recommended way of doing this in the Next API - I believe they only run server-side?

Most helpful comment

@aorsten Yes i implemented it, but i encode the redirect url in state.

In /api/login i do this:

// When i redirect here, i give it the redirect url via query var:
// /api/login?redirect-url=/where/i/was
const redirectUrl = req.query['redirect-url'] || '/';
// I encode the url in state
// I separate it from the random nonce by |
// The random nonce is 32 bytes
const state = Buffer.concat([
    Buffer.from(redirectUrl),
    Buffer.from('|'),
    randomBytes(32)
]);
// And then i pass my custom state via authParams
await auth0.handleLogin(req, res, {
    authParams: {
        state: base64url(state),
    },
});

Then in /api/callback i pull the redirect url back out of state:

const state = base64url.toBuffer(req.query.state || '')
const sep = state.indexOf('|');
const redirectTo =
    sep > 0 && state.length - sep - 1 === 32
        ? state.toString('utf8', 0, sep)
        : '/';
await auth0.handleCallback(req, res, {
    redirectTo,
});

All 6 comments

I ran into this myself today. I believe that it should be possible to pass a custom state value to handleLogin (this is currently not possible). Then the redirect url could be stored as described in https://auth0.com/docs/protocols/oauth2/redirect-users - the callback handler gets passed the state as a query parameter, so the redirect url could be recovered there and then passed via the redirectTo option to handleCallback.

@claus
Have you implemented redirecting?
I'm looking at the auth0 tutorial for redirecting: https://auth0.com/docs/protocols/oauth2/redirect-users

How do you store the nonce locally? As far as I can tell, I need to store it (as cookie or local storage) before routing to /api/login (since the api probably cant store things on the client?), and then somehow retrieve it in /api/callback. Not sure what is a good way to implement this - any hints?

@aorsten Yes i implemented it, but i encode the redirect url in state.

In /api/login i do this:

// When i redirect here, i give it the redirect url via query var:
// /api/login?redirect-url=/where/i/was
const redirectUrl = req.query['redirect-url'] || '/';
// I encode the url in state
// I separate it from the random nonce by |
// The random nonce is 32 bytes
const state = Buffer.concat([
    Buffer.from(redirectUrl),
    Buffer.from('|'),
    randomBytes(32)
]);
// And then i pass my custom state via authParams
await auth0.handleLogin(req, res, {
    authParams: {
        state: base64url(state),
    },
});

Then in /api/callback i pull the redirect url back out of state:

const state = base64url.toBuffer(req.query.state || '')
const sep = state.indexOf('|');
const redirectTo =
    sep > 0 && state.length - sep - 1 === 32
        ? state.toString('utf8', 0, sep)
        : '/';
await auth0.handleCallback(req, res, {
    redirectTo,
});

@aorsten To answer your question, i would store the redirect url in a key/value store like node-cache. I would use the random state as key and the redirect url as value. Haven't tried that though.

@aorsten Yes i implemented it, but i encode the redirect url in state.

In /api/login i do this:

// When i redirect here, i give it the redirect url via query var:
// /api/login?redirect-url=/where/i/was
const redirectUrl = req.query['redirect-url'] || '/';
// I encode the url in state
// I separate it from the random nonce by |
// The random nonce is 32 bytes
const state = Buffer.concat([
    Buffer.from(redirectUrl),
    Buffer.from('|'),
    randomBytes(32)
]);
// And then i pass my custom state via authParams
await auth0.handleLogin(req, res, {
    authParams: {
        state: base64url(state),
    },
});

Then in /api/callback i pull the redirect url back out of state:

const state = base64url.toBuffer(req.query.state || '')
const sep = state.indexOf('|');
const redirectTo =
    sep > 0 && state.length - sep - 1 === 32
        ? state.toString('utf8', 0, sep)
        : '/';
await auth0.handleCallback(req, res, {
    redirectTo,
});

This solution does work to redirect the user after authentication. Though it will allow the user to be redirected anywhere opening the site for phishing attacks. Some control needs to be done to whitelist where they are being directed to!

@brettski Yes definitely, thanks for calling that out. The safest solutions are those outlined in the Auth0 article linked above.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nodabladam picture nodabladam  路  7Comments

shicholas picture shicholas  路  5Comments

davemaier picture davemaier  路  4Comments

lunchboxav picture lunchboxav  路  5Comments

shansmith01 picture shansmith01  路  4Comments