Please include the following information in your post:
SDK: auth0-js
SDK Version: 9.16.0
Platform Version: Node 14.15.5
Application Type: Regular Application (NextJS)
Hello,
I’m trying to implement passwordless flow using the auth0-js SDK. I don’t want to use the Universal Login because the customisation offered are not sufficient enough.
My application is a “Regular Web Application” (NextJS). I’m not using nextjs-auth0 because that again wants me to use Universal Login which isn’t what we want.
We’ve also enabled the Customize Login Page in Auth0 Dashboard → Universal Login → Login → Customize Login Page. As well as enabled the Passwordless OTP
grant for target application.
Following the Auth0 SDK here (Auth0.js v9 Reference) I’ve done the following at high level:
-
Initiate the Passwordless flow at the backend. I have to do the passwordless start at server side since client secret is now required (see this comment from auth0 dev: Passwordless connection not working for tenants created after Jan 2, 2020 - #6 by thameera)
// pages/api/passwordless.js export default async (req, res) => { await axios.post(`https://${process.env.AUTH0_DOMAIN}.au.auth0.com/passwordless/start`, { client_id: process.env.AUTH0_CLIENT_ID, client_secret: process.env.AUTH0_CLIENT_SECRET, connection: 'email', email: 'SOME USER EMAIL', send: 'link', authParams: { // any authentication parameters that you would like to add redirectUri: 'http://localhost:3000/auth/callback', responseType: 'token', }, }); res.status(200);
};
-
user clicks the email link received in their inbox
-
Auth0 redirects to our callback pages (
http://localhost:3000/auth/callback
). The url that /callback has is something like (http://localhost:3000/callback#access_token=7Cl7_LLrWIpuEuuKSghAPRp00000000&scope=openid&expires_in=7200&token_type=Bearer
) -
we handle the callback fragments using:
import React, { Component, useEffect } from 'react'; import { useRouter } from 'next/router'; import auth0 from 'auth0-js'; const auth0 = new auth0.WebAuth({ domain: 'OUR_AUTH0_DOMAIN.au.auth0.com', audience: 'https://OUR_AUTH0_DOMAIN.au.auth0.com/api/v2/', clientID: 'OUR ACTUAL CLIENT ID', redirectUri: 'http://localhost:3000/auth/callback', responseType: 'token', scope: 'openid email offline_access', }); // pages/callback const Callback = () => { const router = useRouter(); const handleAuthentication = () => { return new Promise((resolve, reject) => { auth0.parseHash((err, authResult) => { if (authResult && authResult.accessToken && authResult.idToken) { this.auth0.client.userInfo(authResult.accessToken, (err, user) => { if (err) { reject(err); } resolve(user); }); } else if (err) { reject(err); window.location.replace('/'); } }); }); }; useEffect(() => { handleAuthentication() .then((res) => { router.push('/protected_page'); }) .catch((err) => { router.push('/'); }); }, []); return <div />; }; export default Callback;
-
The auth0.parseHash at this point gives an error saying
{error: "invalid_token", errorDescription: "`state` does not match."}
At this point i don’t know what i’m doing wrong Is there a working example somewhere of how we’re meant to implement passwordless flow using auth0-js and regular application without using Universal Login? Would highly appreciate an example.
I also get this error ({error: “consent_required”, error_description: “Consent required”}) but i understand this is a localhost thing so i’m not too concerned about this for now.
To Auth0:
- Documentation of auth0-js isn’t updated anymore? If i just use the code sample from the documentation, that simply does not work.
Anyone knows what i’m doing wrong?
Thanks