Sign with Redirect
Once the authentication is complete, we will get the user's JoyID information, such as username, address, credential, etc. In this guide, we will continue our previous journey in Auth with Redirect by signing a challenge after the authentication is complete.
To redirect to JoyID App to sign a challenge, we need to do the following steps:
Step 1: Save authentication info
In the previous guide, we have already authenticated the user with JoyID, and we have got the user's JoyID information. Now we need to save the user's JoyID information. We can save it in the local storage, or in the state of the React component, or in the Vuex store of the Vue app, etc.
import * as React from 'react';
import { authWithRedirect, authCallback } from '@joyid/core';
import './style.css';
export default function App() {
const [authInfo, setAuthInfo] = React.useState(null);
const isRedirectFromJoyID = new URL(location.href).searchParams.has(
'joyid-redirect'
);
const authOnClick = async () => {
authWithRedirect({
redirectURL: location.href,
name: 'Awesome App',
challenge: 'Sign this for me',
logo: 'https://reactjs.org/logo-180x180.png',
});
};
React.useEffect(() => {
if (isRedirectFromJoyID) {
const authRes = authCallback();
if (authRes.error == null && authRes.type === 'Auth') {
setAuthInfo(authRes)
}
}
}, []);
return (
<div>
<h1>Hello JoyID!</h1>
<button onClick={authOnClick}>Auth With JoyID</button>
</div>
);
}
Step 2: Sign the challenge
After the authentication is complete, we need to add a button
element and listen to the click
event. When the user clicks the button, we will call the signWithRedirect
function to sign the challenge
with the user's JoyID.
Note that address
is required in the signWithRedirect
function. You can only sign the challenge
with the user's JoyID if you know the user's address. The address
is included in authentication info.
Verify the credential before signing the challenge
import * as React from 'react';
import {
authCallback,
authWithRedirect,
signCallback,
signWithRedirect,
} from '@joyid/core';
import './style.css';
export default function App() {
...
const signOnClick = async () => {
signWithRedirect({
redirectURL: location.origin + '/',
name: 'Awesome App',
challenge,
logo: 'https://reactjs.org/logo-180x180.png',
address: authInfo?.address,
state,
});
};
...
return (
...
<button onClick={signOnClick}>Sign With JoyID</button>
...
);
}
Step 3: Get redirected data
After the user signed with JoyID App, the user will be redirected back to your App with the result in the URL query string. We need to call signCallback
function in your redirected page to get the result.
In this step, we save all UI states and pass to the JoyID App via the state
parameter of signWithRedirect
function. When the signing is done, the same UI states are returned via the signCallback
function, which keeps our UI continuous. But this is not the only way to maintain UI continuity after redirection, you can also save UI state to localStorage or server side, or even just ignore UI continuity.
import * as React from 'react';
import {
authCallback,
authWithRedirect,
signCallback,
signWithRedirect,
} from '@joyid/core';
import './style.css';
const initState = {
authInfo: null,
challenge: 'Sign this for me',
};
type Action = {
type: 'challenge' | 'authInfo';
payload: any;
};
const reducer = (state: typeof initState, action: Action): typeof initState => {
const { type, payload } = action;
switch (type) {
case 'challenge': {
return {
...state,
challenge: payload,
};
}
case 'authInfo': {
return {
...state,
authInfo: payload,
};
}
default: {
return state;
}
}
};
export default function App() {
const isRedirectFromJoyID = new URL(location.href).searchParams.has(
'joyid-redirect'
);
const [state, dispatch] = React.useReducer(reducer, initState);
const { challenge, authInfo } = state;
const authOnClick = async () => {
authWithRedirect({
redirectURL: location.origin + '/',
name: 'Awesome App',
challenge: 'Sign this for me',
logo: 'https://reactjs.org/logo-180x180.png',
state,
});
};
const signOnClick = async () => {
signWithRedirect({
redirectURL: location.origin + '/',
name: 'Awesome App',
challenge,
logo: 'https://reactjs.org/logo-180x180.png',
address: authInfo?.address,
state,
});
};
React.useEffect(() => {
if (isRedirectFromJoyID) {
const authRes = authCallback();
if (authRes.error == null && authRes.type === 'Auth') {
dispatch({ type: 'authInfo', payload: authRes.data });
}
const signRes = signCallback();
if (signRes.error == null && signRes.type === 'SignMessage') {
const { state, ...data } = signRes.data;
const { authInfo, challenge } = state as typeof initState;
dispatch({ type: 'challenge', payload: challenge });
dispatch({ type: 'authInfo', payload: authInfo });
// see console for details
console.log(data);
}
}
}, []);
return (
<div>
<h1>Hello JoyID!</h1>
{authInfo ? null : (
<button onClick={authOnClick}>Auth With JoyID</button>
)}
{authInfo ? (
<div>
<textarea
value={challenge}
onChange={(e) =>
dispatch({
type: 'challenge',
payload: e.target.value,
})
}
/>
<button onClick={signOnClick}>Sign With JoyID</button>
</div>
) : null}
</div>
);
}
signCallback
function, please check the API Reference.